爬虫的初始和requests模块基础用法
-
通用爬虫
-
抓取互联网中的一整张页面数据
-
-
聚焦爬虫
-
抓取页面中局部数据
-
-
-
用来检测网站数据更新的情况,以便爬取到网站最新出来的数据
-
-
爬虫数据的行为风险的体现
-
爬虫干扰了被访问网站的正常运营
-
爬虫抓取了受到法律保护的特定类型的数据或者信息
-
-
规避风险
-
-
在规避反爬虫措施的同时,需要优化自己的代码,避免干扰被访问网站的正常运行;
-
在使用、传播抓取到的信息时,应审查所抓取的内容,如发现属于用户的个人信息、隐私或者他人的商业秘密的,应及时停止并删除。
-
4.robots协议:文本协议
特性:防君子不防小人的文本协议
2.requests 模块的基础用法
1.requests模块
python中封装好的一个基于网络请求的模块
2.requests模块的作用
用来模拟浏览器发送请求
3.requests模块的环境安装:
pip3 install requests
4.requests模块的编码流程
1.指定url
2.发起请求
3.获取数据
4.数据持久化(存储)
5.实例:
-
基于requests模块的get请求
-
需求:爬取搜狗指定词条搜索后的页面数据
-
-
基于requests模块ajax的get请求
-
需求:爬取豆瓣电影分类排行榜 https://movie.douban.com/中的电影详情数据
-
-
基于requests模块ajax的post请求
-
需求:爬取肯德基餐厅查询中指定地点的餐厅数据
-
-
综合练习
-
需求:爬取国家药品监督管理总局中基于中华人民共和国化妆品生产许可证相关数据
-
1.爬取搜狗首页的页面源码数据
import requests
# 1.指定url url = 'https://www.sogou.com/'
# 2.请求发送get,get返回值是一个响应对象 response = requests.get(url=url)
# 3.获取响应数据 page_text = response.text #返回的是字符串形式的响应数据
# 4.数据持久化 with open("sogou.html","w",encoding="utf_8") as fp: fp.write(page._text)
2.爬取搜狗指定词条搜索后的页面数据
# 需要让url携带的参数动态化 url = 'https://www.sogou.com/web' # 实现参数动态化 wd= input('enter a key:') params = { 'query':wd } # 在请求中需要将请求参数对应的字典作用奥params这个get方法的参数中 response = request.get(url=url,parmas=params) page_text = response.text filename = wd + ".html" with open(filename,"w",encoding='utf-8') as fp: fp.write(page_text)
执行上述代码之后发现
- 出现了乱码
- 数据量级不对
解决乱码
url = 'https://www.sogou.com/web' #实现参数动态化 wd = input('enter a key:') params = { 'query':wd } # 在请求中需要将请求参数对应的字典作用到params这个get方法的参数中 response = requests.get(url=url,params=params) response.encoding = 'utf-8' # 修改响应数据的编码格式 page_text = response.text
fileName = wd+'.html' with open(fileName,'w',encoding='utf-8') as fp: fp.write(page_text)
请求载体身份标识的伪装:
-
User-Agent:请求载体身份标识,通过浏览器发起的请求,请求载体为浏览器,则该请求的User-Agent为浏览器的身份标识,使用爬虫程序发起的请求,则该请求的载体为爬虫程序,则该请求的User-Agent为爬虫程序的身份标识。可以通过判断该值来获知该请求的载体究竟是基于哪款浏览器还是基于爬虫程序。
-
反爬机制:某些门户网站会对访问该网站的请求中的User-Agent进行捕获和判断,如果该请求的UA为爬虫程序,则拒绝向该请求提供数据。
-
反反爬策略:将爬虫程序的UA伪装成某一款浏览器的身份标识。
解决UA 检测
import requests url = 'https://www.sogou.com/web' # 实现参数动态化 wd = input('enter a key:') params = { 'query': wd } headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36' } # 在请求中需要将请求参数对应的字典作用到params这个get方法的参数中 response = requests.get(url=url, params=params, headers=headers) # 修改响应数据的编码格式 response.encoding = 'utf-8' page_text = response.text fileName = wd + '.html' with open(fileName, 'w', encoding='utf-8') as fp: fp.write(page_text)
3.爬取豆瓣电影分类排行榜中的电影详情数据
# 爬取的是豆瓣电影中电影的详情数据https://movie.douban.com/typerank?type_name=%E7%88%B1%E6%83%85&type=13&interval_id=100:90&action= # 分析:当滚动条被滑动到页面底部的时候,当前页面发生了局部刷新(ajax的请求) # 动态加载的页面数据 是通过另一个单独的请求请求到的数据 import requests url = "https://movie.douban.com/j/chart/top_list" start = input("您想从第几部电影开始获取:") limit = input('您想获取多少电影数据:') # 参数动态化, dic = { 'type': '13', 'interval_id': '100:90', 'action': '', 'start': start, 'limit': limit, } headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36' } response = requests.get(url=url, params=dic, headers=headers) page_text = response.json() # json()返回的是序列化好的实例对象 for dic in page_text: print(dic['title']+':'+dic['score'])
4.爬取肯德基餐厅详情
import requests url = "http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword"
headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36' }
data = { "cname": "", "pid": "", "keyword": "西安", "pageIndex": 1, "pageSize": 10 } response = requests.post(url=url, data=data, headers=headers) print(response.json())
如何检测页面中是否存在动态加载的数据?
-
-
先捕获网站请求后所有的数据包
-
在数据包定位到地址栏所对应的请求的数据包,在response选项卡对应的数据中进行局部搜索(页面中的某一组内容) (按ctrl+f组合)
-
可以搜索到:爬取的数据不是动态加载的
-
没有搜索到:爬取的数据时动态加载的
-
-
如何定位动态加载的数据在哪个数据包中呢?
-
进行全局搜索
-
-
5.爬取国家药品监督管理总局
# 需求 爬取药监总局中相关企业的详情信息http://125.35.6.84:81/xk/ # 需求分析 # 确定页面中企业相关数据是否为动态加载 相关的企业信息是动态加载出来的
# 通过抓包工具实现全局搜索,定位动态加载数据对应的数据包 post: http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsList 该请求返回的响应数据是一组json串,通过对json串的简单分析,没有找到企业详情页的url,但是找到每一家企业的id
# 每一家企业的详情页的url域名都是一样的,只有请求参数id不同 可以使用同一个域名结合不同企业的id值拼接成一家完整企业详情页url
# 判断企业详情页中的数据是否为动态加载? 通过抓包工具进行检测,发现企业详情信息在详情页中为动态加载的数据 通过抓包工具实现实现全局搜索定位动态加载数据对应的数据包 post-url ;http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsById 请求携带的参数: id=xxxx 请求到的json串就是我们最终想要的企业详情信息数据
import requests url = "http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsList" headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36' } # 获取前5页的内容 for page in range(1, 6): data = { "on": "true", "page": str(page), "pageSize": "15", "productName": "", "conditionType": "1", "applyname": "", "applysn": "", } company_data = requests.post(url, headers=headers, data=data).json() for dic in company_data["list"]: _id = dic["ID"] datail_url = "http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsById" data = { "id": _id } detail_data = requests.post(url=datail_url, headers=headers, data=data).json() print(detail_data["epsName"], detail_data["legalPerson"])
待续