(转)Python新手写出漂亮的爬虫代码2——从json获取信息

 

https://blog.csdn.net/weixin_36604953/article/details/78592943html

 

Python新手写出漂亮的爬虫代码2——从json获取信息
很久没有写关于爬虫的东西了,若是正在读这篇博客的你看过个人另外一篇《Python新手写出漂亮的爬虫代码1——从html获取信息》想必已经对一些写在html中的信息进行过爬取了,今天给你们介绍一下另外一种爬虫——动态爬虫。python

1.静态爬虫与动态爬虫
何为动态爬虫,html中的信息是静态的,或者说是经过html语言生成了网页中的对应信息,是写好的,你把网页的html源代码粘贴过来,你要的信息就在里面,这种状况下就是静态爬虫,而有的时候咱们会发现咱们须要的信息不在html源码中,好比电商网站的评论,某些网站的一些条形图啊,折线图啊,(这些图其实是数字,只是经过某种接口传到网页上,而后渲染成了图的形式,其本质上是数字),这些可能频繁更新的信息(好比评论每小时甚至每分钟都在更新),这时候,若是将它写在html中,是一个很难受的过程,由于有一个新评论你就要改写html,因此对于这种状况,咱们想要的数据都会存在一个json文件中。正则表达式

这里须要作一个说明,咱们看网页源代码,经过在网页上鼠标邮件,点选“查看网页源代码”出来的才是html源码,而经过F12调出的开发者工具中的element或元素中的那些,不是html代码,而是html代码的一个超集,它比真实的html代码内容要多,因此查看信息是否在html中仍是须要点选“查看网页源代码”才准确。json

2.json
json是一种数据格式,相似于python中的字典,以key:value的形式存储信息,是一种目前愈来愈经常使用的方便的数据存储方式。浏览器

3.动态爬虫思路
动态爬虫较静态爬虫而言难点在于定位数据或信息的存储位置,而一旦获取了这个位置(json文件对应的url),那么就很是简单了,使用python的json库能够对json数据轻松的解析,说白了只是根据你要的key提取其value而已,因此动态爬虫是比较简单的(固然,这里还有另外一个问题,是异步加载问题,这个之后有机会再讲,异步加载是啥?好比说某个网页,没有“下一页”按钮,而是用鼠标滚轮或者屏幕右侧的滑块,向下滑就会刷新,你连往下刷多久会到底都不知道,这就是异步加载,异步加载能够经过抓包工具去解决,也可使用selenium模拟鼠标点击去解决,之后会讲到)。app

4.定位json存储位置
定位json的位置一般是经过“换页”来查看Network的变动,在网页上按F12打开开发者工具,界面放到Network中,而后换页,查看“js”或是“XHR”中文件的更新,而后一一查看更新的json文件,来定位咱们须要的信息在哪里。dom

5.实例讲解
说了这么多你可能仍是有点儿糊涂,不要紧,来个例子就懂了,就拿天猫的一个女装来讲吧,其url为https://detail.tmall.com/item.htm?spm=a1z10.3-b-s.w4011-14681080882.119.17398fc89ncLzj&id=529355863153&rn=ec60f51904f6286d9b2d8bb02c8ca5a8&abbucket=5
(这个模特身材还不错哈哈)异步

请看图1,咱们点击红色方块中的“累计评价”,就能够看到以往的评价,按照咱们前一篇爬虫的讲解来讲,这个信息可能在html代码中,好,那么咱们看一看,按下F12,如图2所示。 scrapy


图1
图2中的1和2位置能够看到,评论仿佛是在一个标签中的,可是还记得我前面的说明么,你在这里看到的html代码是真实html代码的一个超集,比实际的html代码要多,那么咱们右键鼠标,选择“查看网页源代码”,并把源码复制粘贴到文本编辑器中,查找图2中1对应的评论,结果如图3所示。编辑器

 

图2
图3中居然没有搜索到这个评论,也就是说图2的开发者工具欺骗了咱们,too young too sample,sometime naive,哈哈,不要紧,之后每次爬虫以前都这么看一看,就知道你要的信息是否是在html中了。好了,既然不在html中,那么咱们须要去寻找咱们想要的信息在哪里了。

 

图3
按照图4,在开发者工具中选择“Network”,来查看网页其余组件信息。


图4
如图5的红色方块,点击“JS”,不出之外应该是空的,固然若是你那里不是空的也无所谓,无伤大雅,咱们要的数据就在JS下,只是如今还未显示出来(还有一些状况,尤为是折线图这些图像形式的数据,通常会存储在XHR下,也就是图5中的粉色圈中,也是.json形式的),接下来咱们就要去寻找存储评论数据的json文件了。


图5
此时“JS”下的界面如图5所示,有多是空的,固然也可能会有一些其余的东西,接下来看图6,点击图6中A处页码“2”,将评论页切换到第二页,这时候你会发现B处,也就是JS界面中出现了一个文件(若是你先前图5中有内容,那此时应该是多出一个文件),这个文件叫“list-detail**********”。咱们的数据就存放在这里。

有些时候,你换页后可能会出现或新增多个json文件,不过通常都不会不少,最多也就5个,你只须要挨个点进去看看哪一个存放了你须要的信息便可。


图6
接下来,咱们双击这个文件,或者单击选中这个文件,复制其url而后粘贴到浏览器的地址栏中也可,其内容如图7所示,这里红框标出了其前三条评论。由于咱们是在评论的第二页打开的这个json,因此它对应的是第二页的评论内容,而网页中第二页评论的前三条如图8所示。

 

图7
能够看到,数据对上了,咱们已经成功的定位到了评论的位置,图7的json诚如各位所见,是一个字典的形式,评论内容对应的key为”rateContent”。

 

图8
接下来看一下评论的页码是怎么控制的。如图9所示,其实两个url只差了之歌数字,就是图9红框标出的”currentPage=”后面的数字,若是是第一页,数字就是1,若是是第二页,数字就是2。好了,换页规律找到了,剩下就是解析json了,就是最简单的一步。

 

图9
关于json的解析我不许备过多解释了,有python基础的朋友必定对json这个库不陌生,我在代码中以注释的方式给出吧。本例代码使用Python3。

6.代码实战
import urllib
import urllib.request
import re
from bs4 import BeautifulSoup
import time
import random
import json
import math

# 建立一个文件存储评论及其余数据
myfile = open("tm_fz_gn_1_1_1.txt","a")
# 共获取四个变量,评论者昵称,是否超级会员,评论时间,评论内容
print("评论者昵称","是否超级会员","评论时间","comment",sep='|',file=myfile)
stop = random.uniform(0.5,2)

# 获取页数
try:
url0 = "https://rate.tmall.com/list_detail_rate.htm?itemId=544442011638&spuId=718591114&sellerId=196993935&order=3¤tPage=1&append=0&content=1&tagId=&posi=&picture=&ua=025UW5TcyMNYQwiAiwQRHhBfEF8QXtHcklnMWc%3D%7CUm5Ockp3S39AeU13QnhDeC4%3D%7CU2xMHDJ7G2AHYg8hAS8XIw0tA18%2BWDRTLVd5L3k%3D%7CVGhXd1llXWBcaFduWmBVb1RvWGVHe0Z9SXRLc05zRnlDfkZ6VAI%3D%7CVWldfS0TMww1CioWIgIsCCNMMWwyVDlrME8iakFhXn5BZEocSg%3D%3D%7CVmhIGCUFOBgkGiMXNwwzBzsbJxkiGTkDOA0tES8ULw81Cj9pPw%3D%3D%7CV2xMHDIcPAA%2FASEcPAM4Az9pPw%3D%3D%7CWGBAED4QMGBaZ1p6RXBKc1NoXWBCfUh0S3NTbVBqSnROblBkMhIvDyEPLxciGSx6LA%3D%3D%7CWWBdYEB9XWJCfkd7W2VdZ0d%2BXmBdfUF0Ig%3D%3D&isg=AnBwr9DL3fao4YAwe7Eb61VPQT4CEVRrBvSVMGrBPUueJRHPEskkk8YHCxu-&needFold=0&_ksTS=1501924984733_1070&callback=jsonp1071"
req0 = urllib.request.Request(url0)
req0.add_header('User-Agent','Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36')
html0 = urllib.request.urlopen(req0,timeout=500).read()
html0 = bytes.decode(html0,encoding="gbk")
# print(type(html0))
'''
下面这一步是由于这个json不是标准的json,json是一个完彻底全的字典,而这个json是在相似json1234()这个结构的括号中,打开看看这个json你就懂了,因此须要用正则表达式去获取真实的json(即字典)
'''
js0 = re.search('{"rateDetail(.*)',html0).group()[:-1]
# 将json主要内容存入content
content0 = json.loads(js0)
content = content0['rateDetail']
# print(content.keys())
# print(json.dumps(content0, sort_keys=True, indent=2))
#尾页
lastpage = int(content['paginator']['lastPage'])
except:
print("获取尾页失败,默认爬取99页")
lastpage = 99

# 构造循环遍历每一页for i in range(1,lastpage): try: url = 'https://rate.tmall.com/list_detail_rate.htm?itemId=544442011638&spuId=718591114&sellerId=196993935&order=3¤tPage='+str(i)+'&append=0&content=1&tagId=&posi=&picture=&ua=025UW5TcyMNYQwiAiwQRHhBfEF8QXtHcklnMWc%3D%7CUm5Ockp3S39AeU13QnhDeC4%3D%7CU2xMHDJ7G2AHYg8hAS8XIw0tA18%2BWDRTLVd5L3k%3D%7CVGhXd1llXWBcaFduWmBVb1RvWGVHe0Z9SXRLc05zRnlDfkZ6VAI%3D%7CVWldfS0TMww1CioWIgIsCCNMMWwyVDlrME8iakFhXn5BZEocSg%3D%3D%7CVmhIGCUFOBgkGiMXNwwzBzsbJxkiGTkDOA0tES8ULw81Cj9pPw%3D%3D%7CV2xMHDIcPAA%2FASEcPAM4Az9pPw%3D%3D%7CWGBAED4QMGBaZ1p6RXBKc1NoXWBCfUh0S3NTbVBqSnROblBkMhIvDyEPLxciGSx6LA%3D%3D%7CWWBdYEB9XWJCfkd7W2VdZ0d%2BXmBdfUF0Ig%3D%3D&isg=AnBwr9DL3fao4YAwe7Eb61VPQT4CEVRrBvSVMGrBPUueJRHPEskkk8YHCxu-&needFold=0&_ksTS=1501924984733_1070&callback=jsonp1071' req = urllib.request.Request(url) req.add_header('User-Agent','Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36') html = urllib.request.urlopen(req,timeout=500).read() html = bytes.decode(html,encoding="gbk") js = re.search('{"rateDetail(.*)', html).group()[:-1] infos0 = json.loads(js) infos = infos0['rateDetail']['rateList'] tiaoshu = 0 for info in infos: try: tiaoshu += 1 time.sleep(stop) ss = "正在爬取第%d页的第%d条评论,共%d页" % (i,tiaoshu,lastpage) print(ss) # 用户姓名 try: user_name = info['displayUserNick'].strip().replace('\n','') except: user_name = "" # 是否黄金会员 try: user_status = info['goldUser'].strip().replace('\n','') except: user_status = "" # 评论时间 try: comment_date = info['rateDate'].strip().replace("\n","") except: comment_date = "" # 评论内容 try: comment = info['rateContent'].strip().replace("\n","").replace('\t','') except: comment = "" print(user_name,user_status,comment_date,comment,sep='|',file=myfile) except: sss = '爬取第%d页的第%d条评论失败,跳过爬取' % (i,tiaoshu) print(sss) pass except: print("该产品url获取失败,请检查")myfile.close()12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485到此,爬虫的第二课——从json获取信息就结束了,之后会陆续退出selenium、异步加载、scrapy的使用教学和案例。敬请关注哈~--------------------- 做者:夏洛克江户川 来源:CSDN 原文:https://blog.csdn.net/weixin_36604953/article/details/78592943 版权声明:本文为博主原创文章,转载请附上博文连接!

相关文章
相关标签/搜索