爬虫python实例,python爬虫实战案例

  爬虫python实例,python爬虫实战案例

  学习笔记

  文章目录Ajax动态加载网站数据抓取动态加载的类型那么如何抓取数据呢?如何获取JSON文件的地址?观察JSON文件URL地址的查询参数。如何将JSON格式数据转换成python字典获取科研数据

  前几天小伙伴在写报告的时候,讨论了一个生态网站的抓取统计问题。我看了看,想了想。很多数据网站的数据都是动态加载的,写个案例就好,方便数据收集整理。

  在爬取数据之前,我先讲一些关于动态加载网站的知识点,让你理解代码。

  动态加载的类型部分页面刷新的动态加载

  首先,我们来看一个动态加载的网站(这个网站也是我们后面要抓取的网站):

  当我们翻页时,URL地址不会改变。网站只刷新部分页面,只有表格中的数据发生变化,而页面的其余部分没有变化:

  滚动自动触发页面加载。

  我们来看一个大家都很熟悉的动态加载网站,某东。当我们在一个东页搜索【华章数学】时,会出现以下页面:

  我们检查这些元素,以查看当前页面中最后一项的HTML结构:

  通过观察,我们发现每个商品都被包裹在一个li标签中,那么当前页面的最后一个商品应该被包裹在最后一个li标签中。现在让我们滑动鼠标滚轮,并在滑动页面时观察HTML页面结构:

  哦亲爱的!我们发现滑到底部,页面自动加载了很多李标签包装的新品,页面的URL地址不变。

  那么,如何获取数据呢?

  我们可以看到在动态加载的页面下,URL很弱,无法使用静态匹配的方法抓取动态加载页面中的数据,那么如何抓取信息呢?

  需要注意的是!只要是动态加载的网站,当我们与网站进行交互时,网站都会以JSON格式返回给我们信息,其中包含了我们要抓取的数据。至此,只要找到这些JSON文件的地址,就已经大获成功了。

  如何获取JSON文件的地址?

  我们使用的数据来自安徽省生态与环境厅(http://sthjt.ah.gov.cn/site/tpl/5391?CityCode=340100)为例,我们发现在这个网页中翻页时,只有部分页面信息被刷新,页面的URL地址保持不变,所以网站应该是动态加载数据的。

  打开某#省生态环境厅网页后,右键打开审核元素——点击网络——点击全部——翻页,获取网站与我们交互的数据包——点击预览,确定数据包中是否有我们想要的数据——点击表头,查看数据包的表头信息:

  让我们注意一下Headers中基本请求信息(General)中的请求URL。这个URL地址就是我们需要的JSON文件的URL地址。让我们打开这个地址来验证:

  非常好!那是你。但是…这些JSON数据的格式看起来很混乱。这么多\转义字符是怎么回事?虽然这个问题不影响我们以后的数据抓取,但是我会先标记这个问题,以后再解决。

  让我们回到请求头的头,看看查询参数:

  这些查询参数是JSON文件的URL地址的查询参数。如果你不相信我,我们来对比一下这些查询参数和JSON文件的URL地址:

  #JSON文件的URL地址

  http://sthjt.ah.gov.cn/site/label/8888?isa jax=1 dataType=JSON _=0.6245771911926585 is JSON=true city code=340100 type=1 num=2 is page=true page index=3 pageSize=10 label name=air quality

  #查询参数

  伊萨亚斯:1

  数据类型:json

  _:0.6245771911926585

  isJson:对

  城市代码:340100

  类型:1

  数量:2

  isPage:真的

  页面索引:3

  页面大小:10

  标签:空气质量,嗯!没错!

  那么这些查询参数有什么用呢?就像我们之前在抓取静态网页的数据时需要观察多个URL地址的查询参数的规则一样。如果我们要抓取动态页面中的数据,数据可能不仅仅在一两个JSON文件中,还可能在大量的JSON文件中。这时候我们需要通过观察查询参数的规则,批量获取我们需要的JSON文件的URL地址,从而获取JSON文件中的数据。

  观察JSON文件URL地址的查询参数

  我们通过多次翻页来观察查询参数的规律。

  第1页:

  伊萨亚斯:1

  数据类型:json

  _:0.9632859283976705

  isJson:对

  城市代码:340100

  类型:1

  数量:2

  isPage:真的

  页面索引:1

  页面大小:10

  名称:空气质量第2页:

  伊萨亚斯:1

  数据类型:json

  _:0.699042424499402

  isJson:对

  城市代码:340100

  类型:1

  数量:2

  isPage:真的

  页面索引:2

  页面大小:10

  名称:空气质量第3页:

  伊萨亚斯:1

  数据类型:json

  _:0.6245771911926585

  isJson:对

  城市代码:340100

  类型:1

  数量:2

  isPage:真的

  页面索引:3

  页面大小:10

  名称:空气质量我们发现除了_和pageIndex在翻页时发生了变化外,其他查询参数保持不变。

  我对this _ query参数的规则有点困惑。让我们看看是否可以通过从URL地址中删除这个查询参数来访问JSON文件。

  移除_ query参数后第3页JSON文件的URL地址:

  http://sthjt.ah.gov.cn/site/label/8888?is Ajax=1 data type=JSON is JSON=true city code=340100 type=1 num=2 ispage=true page index=3 pagesize=10 label name=air quality访问结果:

  当然可以!删除_ query参数并不妨碍我们获取JSON文件;同时我们对比网页第3页的数据,和一毛钱一样。

  现在我们看pageIndex的查询参数,可以看到第一页的pageIndex的参数值是1,第二页是2,第三页是3,所以我们推断第二页的pageIndex的查询参数值是。现在我将pageIndex的参数值改为4,并访问这个URL地址:

  对比网页中第4页的数据,完全一样。

  JSON格式的数据被转换成python字典

  现在我们已经整理好了JSON文件的URL地址,就可以抓取网页,获取网页内容了。但是!请注意,我们如何获取JSON文件中的数据?我们看到JSON的数据格式,有点像python中的字典和列表。要爬取的数据由数据键对应的值(一个列表)包装;每个记录都在一个列表中,包装在一个字典中:

  {数据:[

  {

  aqi: 54 ,

  区域:合肥市:

  城市代码:340100,

  一氧化碳: 0.363 ,

  级别,级别: II ,

  度量值: ,

  第二名:“30分钟”,

  o3: 115 ,

  pm10: 57 ,

  pm25: 16 ,

  主要污染物:“颗粒物质(PM10)”,

  质量:“好”,

  二氧化硫: 7 ,

  时间点: 2020-04-15 18:00:00 ,

  不健康:“”

  },

  {

  aqi: 49 ,

  区域:合肥市:

  城市代码:340100,

  一氧化碳: 0.334 ,

  级别,级别:我,

  度量值: ,

  第二名:“22”,

  o3: 123 ,

  pm10: 49 ,

  pm25: 15 ,

  primary pollutant:“—”,

  质量:“优秀”,

  二氧化硫: 7 ,

  时间点: 2020-04-15 17:00:00 ,

  不健康:“”

  }],

  页数:5,

  pageIndex: 4,

  页面大小:10,

  起始号码:40,

  总数:47

  }但仔细观察后发现,这些数据格式与字典略有不同,不能直接用字典索引来获取数据。所以我们想把JSON格式的数据转换成python字典类型,方便获取数据。

  但是怎么转换呢?

  请求模块是我们的好帮手。使用requests.get()。json()方法可以直接返回python的数据类型。

  语法:

  Html _ str=requests.get (URL,headers=headers)。JSON()应该返回一个字典,但是!不知道为什么,它返回给我一个包含字典的字符串?我不要字符串,我要字典!现在我在网上找到了两种将字符串转换成字典类型的方法。让我们来演示一下:

  In [43]: str_01={a:1}

  在[44]中:键入(json.loads(str_01))

  Out[44]:字典

  在[45]中:键入(eval(str_01))

  Out[45]:字典

  如何获取科研数据?现在我们回到如何获取科研数据的问题上来。这里我就以我和朋友要爬的网站为例,也就是刚才一直在讲解的安徽省生态环境厅网站:

  在这种情况下,我得到网页中的aqi(质量指数)、cityCode(城市代码)和pm25(PM2.5)的值。

  PS:因为我懒得打那么多代码,你可以举一反三,得到其他变量值。

  好,开始输入代码:

  # -*-编码:utf-8 -*-

  导入请求

  导入时间

  导入csv

  导入json

  类别DeeSpider:

  def __init__(self):

  self . URL= http://sth JT . ah . gov . cn/site/label/8888? isa jax=1 dataType=JSON is JSON=true city code=340100 type=1 num=2 is page=true page index={ } pageSize=10 label name=air quality

  self . headers={ Accept : application/JSON,text/javascript,*/*;q=0.01 ,

  接受-语言: zh-CN,zh;q=0.9 ,

  连接:保持活动,

  主持人: sthjt.ah.gov.cn ,

  用户代理: Mozilla/5.0(Windows NT 6.3;WOW64) AppleWebKit/537.36 (KHTML,像壁虎一样)Chrome/63 . 0 . 3239 . 84 Safari/537.36 ,

  x-Requested-With : XMLHttpRequest }

  def get_data(self,url):

  html=requests.get(url,headers=self.headers)。json()

  #你得到的是一串。

  打印(类型(html))

  html _ dict=JSON . loads(html)[ data ]

  #html_dict=html[data]

  #用于循环每个记录的数据

  data_list=[]

  对于html_dict中的数据:

  aqi=数据[aqi]

  cityCode=data[cityCode]

  pm25=数据[pm25]

  #打印(城市代码)

  data_list.append([aqi,cityCode,pm25])

  self.write_data(数据列表)

  def write_data(self,data_list):

  带开(。/test/my_DeeData.csv , a ,newline= )作为f:

  writer=csv.writer(f)

  #writer.writerow([aqi , cityCode , pm25])

  writer.writerows(data_list)

  def main(自身):

  对于范围(1,5)中的项目:

  url=self.url.format(item)

  self.get_data(url)

  if __name__==__main__ :

  start=time.time()

  spider=DeeSpider()

  spider.main()

  end=time.time()

  Print(执行时间:%.2f%(结束-开始))控制台输出:

  类别“str”

  类别“str”

  类别“str”

  类别“str”

  执行时间:1.15部分数据爬下(共37次):

  85,340100,63

  93,340100,69

  94,340100,70

  92,340100,68

  88,340100,65

  85,340100,60

  85,340100,49

  82,340100,43

  84,340100,44

  87,340100,41

  87,340100,35

  3,340,100,31.很好!所有的数据都爬了下来。

  但是要注意!虽然这个数据网站的页面上注明有47条数据,总共有5页,但实际上只有37条数据,我无法点击第五页:

  将JSON的URL地址中的查询参数pageIndex设置为5,得到的响应是系统忙:啊

  本案例讲完了,欢迎补充、指正和指导。

  备注:虽然看起来我们花了这么多心思,数据不多,但重要的是要明白如何举一反三。

  转载请联系作者获得转载授权,否则将追究法律责任。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: