爬虫初学——爬取京东商品的评论(二)

酱菜Seven7原创,转载请注明出处。

使用的手段:数据库Mysql, 语言python,正则表达式re
在获取了评论url的情况下(获取京东评论的url方法),现在我们可以来爬取用户昵称和url了。作为一个初学者,我用的正则表达式,来对那url的数据,进行匹配获取。
一、根据内容,编写合适的正则表达式
通过分析打开的url地址的数据,我们可以找到所需的两个规律:
1、用户昵称部分
在这里插入图片描述
所以,我们针对提取用户的正则表达式如下:

r'\"nickname\":\"([^",]+)\",\"replyCount2\"'

2、评论部分:
评论部分,因为会有无追评,而造成结尾不一致:
情况一:
在这里插入图片描述
情况二:
爬虫初学——爬取京东商品的评论(二)_第1张图片
匹配评论的正则表达式为:

r'\"content\":\"([^"]+)\",\"(?:creationTime|vcontent)\"'

二、爬取数据的主要代码:
代码功底不好,不要嫌弃,而且赶时间,能用就行,哈哈哈哈哈
导入的库:

import requests
import re
import pymysql

第一部分
在此部分,我是组装url,循环4类评论。然后每一类,循环页码,这样就可以读取每类每页的url的数据,再调用方法来爬取了。我是创建了数据库的四个表,分别存储,要是没有这个需求的,存一个表就好了。

if __name__ == "__main__":
	#每次更换商品时,记得更改所要存入的表名。
    table_list = creat_table("comment33")         #创建4个数据库表,并得到列表
    for index in range(4):             #构建4种评论的url
        print("当前在的阶段为......................................................................"+ str(index))


        '''全部:0,差:1, 中:2, 好:3'''
        #每次更换商品,只需要修改base_url_part1部分的url。后面几部分,是无需修改的。
        base_url_part1 = "https://club.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98&productId=100007651578&score="
        base_url_part2 = str(index)
        base_url_part3 = "&sortType=5&page="
        base_url_part4 = "0"                #此为评论页码
        base_url_part5 = "&pageSize=10"
        base_url = base_url_part1 + base_url_part2 + base_url_part3 +base_url_part4 + base_url_part5


        commentCount = get_CommentCount(base_url)      #获取全部的评论数
        pagenum_max =  int(commentCount / 10 )       #京东设置为每页10个用户的评论,计算评论页面数目(即使总评论很多,网站上也提供有限的评论)
        for pagenum in range(pagenum_max):
            print("current pagenum is ..............:  " + str(pagenum))

            '''pagenum页码,循环每页,获取数据'''
            url = base_url_part1 + base_url_part2 + base_url_part3 + str(pagenum) + base_url_part5
            fake_headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36'
            }
            response = requests.get(url, headers = fake_headers)
            print(response.status_code)
            
            try:
                page_connent = response.content.decode('gbk')
            except UnicodeDecodeError as err:
                print("catch UnicodeDecodeError.....!")
                continue

            # page_connent = response.content.decode('gbk')
            currentPage_user , currentPage_comment = get_comment(page_connent)
            if currentPage_user == [] or currentPage_comment == []:              #如果用户昵称不存在,则可认为已经没有评论了,终止执行
                break
            input_database(currentPage_user , currentPage_comment, table_list[index])       #存入数据库

第二部分:代码自动创建四个数据库表
主要是想偷懒,当时一个商品的评论放一类,所以会建很多数据库表,所以就让代码来创建了。当然,如果没有需求的,一个表存个几万几十万数据也是可以的。

def creat_table(table_baseName):
    '''实现自动创建数据库表(4个),避免手动创建,table_name是表名'''
    table_list = []
    #组装sql语句,创建4个表
    sql_part1 = "CREATE TABLE IF NOT EXISTS `"
    # sql_part2 = "comment6"
    sql_part3 = "`( `id` INT UNSIGNED AUTO_INCREMENT,\
                `product` VARCHAR(100) ,\
                `username` VARCHAR(40),\
                `comment` LONGTEXT,\
                PRIMARY KEY ( `id` )\
                )ENGINE=InnoDB DEFAULT CHARSET=gbk;"
    for i in range(4):
        db = pymysql.connect(host="localhost",user="root",password="123456",db="jdcomment",charset="utf8")
        cur = db.cursor()
        #每次创建表记得修改
        sql_part2 = table_baseName
        if i ==0 :
            sql_part2 = sql_part2
        elif i== 1:
            sql_part2 = sql_part2 + '_bad'
        elif i== 2:
            sql_part2 = sql_part2 + '_middle'
        elif i== 3:
            sql_part2 = sql_part2 + '_good'
        table_list.append(sql_part2)
        sql = sql_part1 + sql_part2 + sql_part3
        cur.execute(sql)        #执行sql语句创建4个表
        print('table creat......!')
        db.commit()
        cur.close() 
        db.close()
    return(table_list)  #返回一个包含4个数据库表名的列表

第三部分:获取评论总数目
当时,以为看到一个商品几十万条,以为可以爬取下来。没想到,最多可见100页,也就是1千条评论。只不过有些评论只有几百条,还是需要来给循环一个参考值吧。评论条数,在请求url返回的数据里面是有的,我用的是正则表达式匹配出来。

def get_CommentCount(base_url):
    '''获取评论总数'''
    fake_headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36'
    }
    response = requests.get(base_url, headers = fake_headers)
    all_content = response.content.decode('gbk')
    # "commentCount":698813,
    re_model = re.compile(r'\"commentCount\":([^,]+),')
    result_list = re_model.findall(all_content)
    commentCount = int(result_list[0])
    return(commentCount)

第四部分:匹配出用户昵称和评论
使用正则表达式匹配,得到的是存储这两类数据的列表。

def get_comment(page_connent):
    '''匹配获取用户昵称和评论,'''
    remodel_user = re.compile(r'\"nickname\":\"([^",]+)\",\"replyCount2\"')             #匹配用户昵称
    username_list = remodel_user.findall(page_connent)

    remodel_comment = re.compile(r'\"content\":\"([^"]+)\",\"(?:creationTime|vcontent)\"')      #匹配评论
    comment_list = remodel_comment.findall(page_connent)
    # print(username_list)
    # print(len(comment_list))
    # print(comment_list)
    return username_list, comment_list

第五部分:存入数据库
将用户昵称和对于的评论,存入我们的MySQL数据库制造。

def input_database(currentPage_user , currentPage_comment, table_name):
    db = pymysql.connect(host="localhost",user="root",password="123456",db="jdcomment",charset="utf8")
    cur = db.cursor()
    for i in range(10):
        '''将每页用户和评论的list,单条取出,一一对应存入数据库'''
        try:
            username = currentPage_user[i]
            comment = currentPage_comment[i]

            #组装sql语句
            sql_part1 = 'INSERT INTO '
            sql_part2 = table_name
            sql_part3 = '(username, comment) VALUES ("'"%s"'", "'"%s"'");'

            sql = sql_part1 + sql_part2 + sql_part3             #组装sql语句,存入不同数据库中

            sql = sql%(username, comment)
            cur.execute(sql)
            print('data input ......ok!')
            db.commit()
        except IndexError as err:
            print("list index out of range")
            continue
    cur.close() 
    db.close()
    print("to next pagenum.......!")

第六部分:数据库中存入的结果
数据库自动创建的表,每次四个,由基础表名决定名称。
爬虫初学——爬取京东商品的评论(二)_第2张图片
表内数据:
(product,这部分,我自己注释了一个,并没有用代码写入)
爬虫初学——爬取京东商品的评论(二)_第3张图片
总结:对于上面的代码,运行使用是没有问题的,如果网络不好,可能在后期请求url会很慢,这是你网络问题。。我设计的是不同商品不同类别评论存入不同表,在使用代码时,也只需要修改“第一部分”代码里面的 creat_table(“comment33”)函数传入的基础表名,和“base_url_part1”的url片段。

作者:酱菜Seven7 注:转载请注明出处

你可能感兴趣的:(爬虫初学——爬取京东商品的评论(二))