失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > python爬虫爬取京东商品评价_京东商品评论爬取实战

python爬虫爬取京东商品评价_京东商品评论爬取实战

时间:2022-11-26 19:28:54

相关推荐

python爬虫爬取京东商品评价_京东商品评论爬取实战

先说说为什么写这个小demo吧,说起来还真的算不上“项目”,之前有一个朋友面试,别人出了这么一道机试题,需求大概是这样紫滴:1.给定任意京东商品链接,将该商品评论信息拿下,存入csv或者数据库

2.要求使用多任务来提高爬虫获取数据的效率

3.代码简洁,规范,添加必要注释

4.可以使用函数式编程,或者面向对象编程 看到上面四个简单的需求,层次高的童鞋可能就看不下去了,因为太简单了,这里本人的目的是给初学爬虫的工程师们。

让我们进入正题吧:step1: 选定任意商品详情url地址

这里我们以:Apple iPhone 7 Plus (A1661) 128G 黑色 移动联通电信4G手机 为例

step2: 按照如下图操作找到评论的url地址:

step3:分析接口数据可知:

step4: 找到目标url并确定数据后,分析目标url接口:

1、分析请求方式,由下图可以看出请求是一个get请求

2、分析url地址规律

注意为了确保找到url地址规律需要多对比不同商品下的评论地址,和同一商品不通分类的url地址

结论:由上面的url可知,同一商品下的不同分页的url只有page值不同,不同商品下的同一分页URL地址,只有productId不同,callback该参数可以省略。

主要获取商品的评论数据如下: 用户头像、用户昵称、星级、内容、产品信息、评论图片地址、评论视频地址、发布时间。

下面开始撸代码:代码思路比较简单step1:导入相关模块

import requests

import re,json

from requests.exceptions import HTTPError,Timeout,RequestException,ProxyError,ConnectTimeout

from concurrent.futures import ThreadPoolExecutor

import csv,pymysql,threading

- step2: 定义一个类JdSpider,完成爬虫主体代码 在__init__初始化方法中添加相关属性

class JdSpider(object):

def __init__(self,start_url):

""":param start_url: 商品url地址"""

#设置商品url地址

self.start_url = start_url

#创建csv文件

self.csv_file = open('jd.csv','a+')

#csv文件头部用户头像headerUrl、用户昵称nickName、星级startLevel、内容content、产品信息productInfo、评论图片地址commentImages、评论视频地址videoUrl、发布时间publishTime。

fileNames = ['headerUrl','nickName','startLevel','content','productInfo','commentImages','videoUrl','publishTime',]

#创建csv文件句柄

self.writer = csv.DictWriter(self.csv_file,fieldnames=fileNames)

#写入csv文件头部

self.writer.writeheader()

#创建数据库链接

self.mysql_client = pymysql.Connect(

host='127.0.0.1', user='root', password="1314",

database='jd', port=3306,charset='utf8'

)

#创建游标

self.cursor = self.mysql_client.cursor()

# 实例化一个lock(互斥锁)

self.myLock = threading.Lock()

self.satrt_request(self.start_url)

- step3: start_request :根据商品url地址发起请求获取响应结果,提取商品的id以及能获取的最大页码数量,拼接商品评论url地址,并将所有请求任务添加进线程池。

def start_request(self,start_url):

#获取商品的id

# match:根据正则表达式,从字符串中提取符合正则表达式的结果,

# 从起始位置开始匹配,如果不符合正则规则,直接返回None,单次

# 匹配

# search:根据正则表达式,从字符串中提取符合正则表达式的结果

# 从整个字符串中匹配符合正则规则的子串,有结果直接返回,否则返回

# None,单次匹配

#/100000177760.html#comment

prodect_id = re.search('\d+',start_url).group()

firstComUrl = "/comment/productPageComments.action?callback=&productId=%s&score=0&sortType=5&page=0&pageSize=10&isShadowSku=0&fold=1" % prodect_id

response_text = self.send_request(firstComUrl)

if response_text:

# print('获取到了数据',response_text)

json_data = json.loads(response_text)

#获取能请求评论的最大页码数量

maxPage = int(json_data['maxPage'])

print('能够获取的最大页码数量',maxPage)

#将任务添加线程池中

pool = ThreadPoolExecutor(10)

for page in range(maxPage):

comUrl = "/comment/productPageComments.action?callback=&productId=%s&score=0&sortType=5&page=%s&pageSize=10&isShadowSku=0&fold=1" % (prodect_id,str(page))

result = pool.submit(self.send_request,comUrl)

result.add_done_callback(self.parse_comments)

pool.shutdown()

- step4: send_request该方法根据url地址使用requests发送请求,返回请求的响应结果

def send_request(self,url,headers={'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36'}):

try:

response = requests.get(url,headers=headers,timeout=10)

if response.status_code == 200:

print('请求成功',response.status_code)

return response.text

except (HTTPError,Timeout,RequestException,ProxyError,ConnectTimeout) as err:

print(err)

return None

- step5: parse_comments解析商品评论接口返回的评论数据,注意这里返回的是一个json字符串,需要使用json.loads将json字符串转换为python数据类型然后取值

def parse_comments(self,future):

response_text = future.result()

if response_text:

#解析数据

comments = json.loads(response_text)['comments']

for comment in comments:

commentInfo = {}

#姓名

commentInfo['nickName'] = comment['nickname']

#内容

commentInfo['content'] = comment['content']

#其他数据依次获取,给你们留点写代码的机会

.......

#存储数据

self.save_db_to_csv(commentInfo)

self.save_db_to_db(commentInfo)

- step6:将数据保存到csv文件

def save_db_to_csv(self,commentInfo):

#将数据写入csv文件

self.myLock.acquire()

self.writer.writerow(commentInfo)

self.myLock.release()

- step7:将数据保存到数据库

def save_db_to_db(self,commentInfo):

#将数据写入数据库

sql = """INSERT INTO jingdong (%s)VALUES (%s)""" % (','.join(commentInfo.keys()),','.join(['%s']*len(commentInfo)))

print(sql,list(commentInfo.values()))

#python中线程安全,

# 加锁

print(self.myLock)

self.myLock.acquire()

try:

self.cursor.execute(sql,list(commentInfo.values()))

mit()

print('插入数据成功')

except Exception as err:

self.mysql_client.rollback()

print(err)

# 解锁

self.myLock.release()

- step9:运行调用程序:

if __name__ == "__main__":

start_url = '/5089253.html'

jdSpider = JdSpider(start_url)

结果如下图所示:

上面代码中只获取了两个字段,其他字段大家可以自行获取了。

如果觉得《python爬虫爬取京东商品评价_京东商品评论爬取实战》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。