文章目录

  • 动态加载数据
  • Ajax的特点
  • 快速验证数据是否为Ajax请求获取得到
  • 爬取某电影网站分类排行榜 - 喜剧片
  • 爬取某餐厅位置信息
  • 爬取某总局企业信息
  • 总结

通过上一篇爬虫入门,已经了解到了爬虫是什么,具体用在哪里,怎么用。
接触到的页面刷新方式是同步刷新,即一打开页面,所有内容都加载出来了。
与之相对的就是 异步刷新Ajax
那么接下来再介绍基于Ajax的页面类型—动态加载数据的页面。

动态加载数据

页面中对应的数据是通过Ajax动态请求到的,即用爬取到的 .html 文件自己建网页是没有数据的。

举个例子

https://movie.douban.com/typerank?type_name=%E5%96%9C%E5%89%A7&type=24&interval_id=100:90&action=

我想要爬取某电影分类排行榜 - 喜剧片(上面的网址),正常不就是四步走嘛:

  1. 指定url
  2. 发起请求
  3. 获得响应数据
  4. 永久化存储
import requestsurl = "https://movie.douban.com/typerank?type_name=%E5%96%9C%E5%89%A7&type=24&interval_id=100:90&action="
head = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 ''Safari/537.36 SLBrowser/7.0.0.12151 SLBChan/30 '
}
response = requests.get(url, headers=head, verify=False)
page_text = response.text
print(page_text)
with open('试验模板.html', 'w', encoding='utf-8') as f:f.write(page_text)
print('爬取数据结束')

看似非常完美没有问题吧,但是嘞,当我用我爬取到的 .html 打开网页时就发现
出大问题了!!!

这爬的是个啥啊,无数据!!!!

为什么会是这样的结果呢,这就不得不提到大名鼎鼎的Ajax了。

Ajax的特点

百度百科:使用Ajax技术网页应用能够快速地将增量更新呈现在用户界面上,而不需要重载(刷新)整个页面,这使得程序能够更快地回应用户的操作。

通俗来说:不用重新加载整个页面,就能够更新部分页面。

还不明白就举个例子:
上面的电影网站是通过滚轮下滑来加载的,每下滑一次就会加载出一些数据

难道说每次爬取前都要通过爬取错误的 .html 才知道网页数据加载是Ajax类型的吗?有没有简便方法?
当然有!

快速验证数据是否为Ajax请求获取得到

  1. F12 + network + 对地址栏网址发请求(回车)。
  2. 在ALL中找地址栏 url 后缀对应的数据包。
  3. 点 response (该url对应的响应数据在response中存放),response中对应的网页源码数据等于requests.get 所请求的数据。
  4. 观察源码中有无包含网页中想要提取的信息,如果源码太多太复杂,可以复制其中一条信息,在response中按 Ctrl + F 打开搜索栏,粘贴刚才复制的信息,如果结果为 0 of 0,则表示地址栏url所对应的数据包所请求到的数据没有包含该信息,进一步说明这些信息是通过Ajax后续加载的,即动态加载的。

就是这种效果⬆

那么如何来获取Ajax类型的页面数据呢?
通过观察网页的开发者工具,发现 Content–Type: 中给了我们答案。

这就需要使用 .json() 方法了

先上代码,

爬取某电影网站分类排行榜 - 喜剧片

import requests
import jsonurl = 'https://movie.douban.com/j/chart/top_list'
head = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (HTML, like Gecko) Chrome/92.0.4515.131 ''Safari/537.36 SLBrowser/8.0.0.2242 SLBChan/11 '
}
param = {'type': '24','interval_id': '100:90','action': '','start': '0',  # 从库中第几部电影去取'limit': '20'  # 一次取多少部
}
response = requests.get(url, params=param, headers=head)
list_data = response.json()
print(list_data)
with open('豆瓣电影.json', 'w', encoding='utf-8') as f:json.dump(list_data, fp=f, ensure_ascii=False)  # 记得缩进!!!!!!
print('爬取数据结束!!!')

这和之前的代码大体相同,总步骤还是四步走。

  • 导入json模块不必多说

  • url不再是网址了,而是需要打开开发者工具, Network–>XHR–>Request URL
    PS:XHR中包含Ajax请求所对应的数据包

  • 以前是response.text , 将响应数据以字符串形式返回。现在是 response.json() , 返回对象类型的响应数据。

  • 存储方式也变了,用 json.dump(存放数据的变量, fp=f, ensure_ascii=False)
    如果还用 f.write() 会报错

  • ensure_ascii=False 是因为 json.dumps 序列化时对中文默认使用的ascii编码,想输出真正的中文需要指定ensure_ascii=False

  • 最后的数据会以 json 格式存储

这样就完成了第一个Ajax页面数据的爬取!


爬取某餐厅位置信息

http://www.kfc.com.cn/kfccda/storelist/index.aspx

import requests
import jsonurl = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx'
head = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (HTML, like Gecko) Chrome/92.0.4515.131 ''Safari/537.36 SLBrowser/8.0.0.2242 SLBChan/11 '
}
word = input('请输入要查询的城市:')
param = {'keyword': word,  'op': 'keyword','cname': '','pid': '','pageIndex': '1','pageSize': '10'
}
response = requests.post(url, params=param, headers=head)
dic_data = response.json()
print(dic_data)
with open('肯德基餐厅位置.json', 'w', encoding='utf-8') as f:json.dump(dic_data, fp=f, ensure_ascii=False)
print('爬取数据成功')

跟上一个一样 , 只不过多加了可变参数 , 简简单单!


爬取某总局企业信息

目标:爬取某服务平台中的各个企业详细信息,即

http://scxk.nmpa.gov.cn:81/xk/itownet/portal/dzpz.jsp?id=6e96e34d97294134b8ad85522c798768
http://scxk.nmpa.gov.cn:81/xk/itownet/portal/dzpz.jsp?id=f42daff75a86437e8bdb6b3392c33b9d
等等

上面这些个企业信息

下面这个是官网

http://scxk.nmpa.gov.cn:81/xk/

import requests
import jsonurl1 = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList'
head = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (HTML, like Gecko) Chrome/92.0.4515.131 ''Safari/537.36 SLBrowser/8.0.0.2242 SLBChan/11 '
}
data1 = {'on': 'true','page': '1','pageSize': '15','productName': '','conditionType': '1','apply name': '','apply': '',
}
response = requests.post(url1, headers=head, data=data1)
dic_data = response.json()
Id_list = []
for id in dic_data['list']:Id_list.append(id['ID'])
url2 = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById'
All_detail_data_list = []
for id in Id_list:data2 = {'id': id}response = requests.post(url2,data=data2,headers=head)detail_data = response.json()print(detail_data)All_detail_data_list.append(detail_data)
with open('药监总局.json','w',encoding='utf-8') as f:json.dump(All_detail_data_list,fp=f,ensure_ascii=False)
print('爬取数据成功!!!')
  1. 先到网站用F12判断出页面数据加载是Ajax类型的

  2. 再从XHR中找到真正的 url , 请求方式 post 和数据类型 json

  3. 接着,把数据通过json形式存储

通过观察发现每个企业网址的不同之处只在 url 最后的 id

http://scxk.nmpa.gov.cn:81/xk/itownet/portal/dzpz.jsp?id=6e96e34d97294134b8ad85522c798768
http://scxk.nmpa.gov.cn:81/xk/itownet/portal/dzpz.jsp?id=f42daff75a86437e8bdb6b3392c33b9d

这样我们只需将首页得到的数据中的id分离出来,通过url和id参数拼接即可得出每个企业的网址。

  1. 首先,解析首页 json 数据

这些就是爬取到的 json 数据

也可以从开发者工具中查看

观察得出, ID 值包含在集合中的 list 元素里,是 list 键的一个值
这样就可以通过遍历字典中 list 元素,来寻找每个ID值了。

Id_list = []
for id in dic_data['list']:Id_list.append(id['ID'])

这就是刚才思路的代码实现,这样 Id_list 中就包含了所有企业 ID, 以列表形式存储。

  1. 判断企业详情页面是否为Ajax类型

    是的,详情页也是Ajax,嵌套两个Ajax。

  2. 每个企业的url和参数拼接
    因为Id_list 中包含了所有企业 ID,所以用循环遍历所有ID并完成请求和获取数据。

for id in Id_list:data2 = {'id': id}response = requests.post(url2,data=data2,headers=head)detail_data = response.json()
  1. 最后,持久化存储,就得到了所有企业的详细数据。

总结

这篇文章解决了在爬虫中遇到动态加载数据(Ajax)的问题。

Python写网络爬虫(二)相关推荐

  1. 网页爬虫python代码_《用python写网络爬虫》完整版+源码

    原标题:<用python写网络爬虫>完整版+源码 <用python写网络爬虫>完整版+附书源码 本书讲解了如何使用Python来编写网络爬虫程序,内容包括网络爬虫简介,从页面中 ...

  2. 《用Python写网络爬虫》——1.5 本章小结

    本节书摘来自异步社区<用Python写网络爬虫>一书中的第1章,第1.5节,作者 [澳]Richard Lawson(理查德 劳森),李斌 译,更多章节内容可以访问云栖社区"异步 ...

  3. 用Python写网络爬虫pdf

    下载地址:网盘下载 作为一种便捷地收集网上信息并从中抽取出可用信息的方式,网络爬虫技术变得越来越有用.使用Python这样的简单编程语言,你可以使用少量编程技能就可以爬取复杂的网站. <用Pyt ...

  4. 用python写网络爬虫 第2版 pd_用Python写网络爬虫(第2版)

    用Python写网络爬虫(第2版)电子书 畅销的Python网络爬虫发实战图书全新升级版,上一版年销量近40000册. 针对Python 3.6版本编写. 提供示例完整源码和实例网站搭建源码,确保用户 ...

  5. python爬取微博恶评_详解用python写网络爬虫-爬取新浪微博评论

    新浪微博需要登录才能爬取,这里使用m.weibo.cn这个移动端网站即可实现简化操作,用这个访问可以直接得到的微博id. 分析新浪微博的评论获取方式得知,其采用动态加载.所以使用json模块解析jso ...

  6. 《用Python写网络爬虫第2版》PDF中英文+代码分析

    互联网包含了迄今为止最有用的数据集,并且大部分可以免费公开访问.但是,这些数据难以复用.它们被嵌入在网站的结构和样式当中,需要抽取出来才能使用.从网页中抽取数据的过程又称为网络爬虫,随着越来越多的信息 ...

  7. 用Python写网络爬虫:推荐这本书看看。

    <用Python写网络爬虫>讲解了如何使用Python来编写网络爬虫程序,内容包括网络爬虫简介,从页面中抓取数据的三种方法,提取缓存中的数据,使用多个线程和进程来进行并发抓取,如何抓取动态 ...

  8. python爬虫教程:Python写网络爬虫的优势和理由

    在本篇文章里小编给各位整理了一篇关于选择Python写网络爬虫的优势和理由以及相关代码实例,有兴趣的朋友们阅读下吧. 什么是网络爬虫? 网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页 ...

  9. 用python写网络爬虫-爬取新浪微博评论

    新浪微博需要登录才能爬取,这里使用m.weibo.cn这个移动端网站即可实现简化操作,用这个访问可以直接得到的微博id. 分析新浪微博的评论获取方式得知,其采用动态加载.所以使用json模块解析jso ...

  10. python网络爬虫的基本步骤-十分钟教会你用Python写网络爬虫程序

    在互联网时代,爬虫绝对是一项非常有用的技能.借助它,你可以快速获取大量的数据并自动分析,或者帮你完成大量重复.费时的工作,分分钟成为掌控互联网的大师. 注意:欲获取本文所涉及的文案,代码及教学视频的链 ...

最新文章

  1. 9.65 最长上升子序列
  2. python之父叫什么-Python之父:为什么操作符很有用?
  3. poj2079(一堆点找出最大的三角形)
  4. 【转载】JAVAEE之内置对象和属性范围
  5. 微博回应用户被“劫持”;途牛否认破产清算;微软宣布开源 MsQuic | 极客头条...
  6. ios弧形进度条_IOS贝塞尔曲线圆形进度条和加载动画-阿里云开发者社区
  7. matlab 图像的膨胀indilate和腐蚀imerode
  8. pt-archiver数据归档
  9. BlenderPython (三)bpy模块
  10. windows7共享打印机无法连接0x00000bcb错误怎么解决
  11. 视频监控流媒体服务器工作原理,流媒体服务器传输基本原理
  12. Java金额转换_阿拉伯数字转换成中国大写数字
  13. Vue Tags Input
  14. steam计算机游戏,steam五款免费游戏推荐  整体品质不输付费游戏 千万不要错过...
  15. 物联网卡解决智能安防系统监控难题,开启全新安防时代
  16. onnx-modifier使用
  17. ORACLE存储过程中打印所有表数据的方法
  18. 游戏盾防御攻击的原理
  19. [翻译 3GPP 38.321] 5.1.1随机接入流程初始化
  20. 程序员为了女朋友进了华为,同学去了阿里,2年后对比收入懵了

热门文章

  1. 园林php源码,园艺和园林绿化HTML5模板
  2. 小米手机二手回收价格大全2022价格表
  3. c语言超声波壁障源码,超声波避障源程序
  4. 低代码指南100方案:88智慧校园后勤管理系统,助力学校后勤管理信息化
  5. 三个分布式计算软件(Prime95、Folding@Home、BOINC)
  6. MySQL基础及GORM框架
  7. 新居客盈门,渠道伙伴售前培训会议-华东场于上海举办
  8. 【转载】无线电干扰分类
  9. 【Pandas学习】读、存excel数据
  10. 本周热榜 · 《计算机自学指南》