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

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

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

好久没有写关于爬虫的东西了,如果正在读这篇博客的你看过我的另一篇《Python新手写出漂亮的爬虫代码1——从html获取信息》想必已经对一些写在html中的信息进行过爬取了,今天给大家介绍一下另一种爬虫——动态爬虫。

1.静态爬虫与动态爬虫

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

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

2.json

json是一种数据格式,类似于python中的字典,以key:value的形式存储信息,是一种目前越来越常用的方便的数据存储方式。

3.动态爬虫思路

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

4.定位json存储位置

定位json的位置通常是通过“换页”来查看Network的变更,在网页上按F12打开开发者工具,界面放到Network中,然后换页,查看“js”或是“XHR”中文件的更新,然后一一查看更新的json文件,来定位我们需要的信息在哪里。

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所示。

图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(" ","")

except:

user_name = ""

# 是否黄金会员

try:

user_status = info["goldUser"].strip().replace(" ","")

except:

user_status = ""

# 评论时间

try:

comment_date = info["rateDate"].strip().replace(" ","")

except:

comment_date = ""

# 评论内容

try:

comment = info["rateContent"].strip().replace(" ","").replace(" ","")

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()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

到此,爬虫的第二课——从json获取信息就结束了,以后会陆续退出selenium、异步加载、scrapy的使用教学和案例。敬请关注哈~

---------------------

作者:夏洛克江户川

来源:CSDN

原文:https://blog.csdn.net/weixin_36604953/article/details/78592943

版权声明:本文为博主原创文章,转载请附上博文链接!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值