爬虫02 /jupyter、爬虫概述、requests基本使用
1. jupyter的基本使用
-
什么是anaconda
- 是一个基于数据分析+机器学习的集成环境。
-
什么是jupyter(超级终端)
- 是anaconda中的一个基于浏览器可视化的编码工具
-
在指定目录下启动终端:录入jupyter notebook指令开启指定的服务。
-
cell的两种模式:cell必须要经过执行才可看到效果
-
MarkDown:编写笔记。兼容markdown的语法和html标签
-
Code:编写代码。
-
-
快捷键
-
插入cell:a,b
-
删除cell:x
-
执行cell:shift+enter
-
tab:自动补全
-
切换cell的模式:y,m
-
打开帮助文档:shift+tab
-
在cell和输出结果间切换 : Esc + O
-
2. 爬虫概述
-
什么是爬虫
- 就是通过编写程序模拟浏览器上网,让其去互联网中抓取数据的过程。
-
爬虫的分类:
- 通用爬虫:爬取一整张页面源码数据。
- 聚焦爬虫:爬取页面中局部的数据。一定是在通用爬虫的基础上实现。
- 数据解析
- 增量式爬虫:用来监测网站数据更新的情况。以便于爬取最新更新出来的数据!
-
爬虫合法性探究:
- 爬虫的风险体现:
- 爬虫干扰了被访问网站的正常运营;
- 爬虫抓取了受到法律保护的特定类型的数据或信息。
- 如何规避风险:
- 严格遵守网站设置的robots协议;
- 在规避反爬虫措施的同时,需要优化自己的代码,避免干扰被访问网站的正常运行;
- 在使用、传播抓取到的信息时,应审查所抓取的内容,如发现属于用户的个人信息、隐私或者他人的商业秘密的,应及时停止并删除。
- 爬虫的风险体现:
-
反爬机制
- robots协议:存在于服务器端的一个纯文本的协议;域名后加/robots.txt即可查看该网站robots协议
- User-Agent:就是请求载体的身份标识。
- 特点:防君子不放小人
- robots协议:存在于服务器端的一个纯文本的协议;域名后加/robots.txt即可查看该网站robots协议
-
反反爬策略
-
http的头信息
- User-Agent
- Connection:'close'/'keep-alive'
- content-type
3. requests模块的基本使用
-
基于网络请求的模块。
-
环境的安装:pip install requests
-
作用:模拟浏览器发起请求
-
分析requests的编码流程:
- 1.指定url
- 2.发起了请求
- 3.获取响应数据
- 4.持久化存储
-
参数动态化
- 设置一个字典,键值就是请求携带的请求参数,需要作用到data/params
-
动态加载数据
- ajax,js
-
需求:爬取搜狗首页的页面源码数据
import requests # 1.指定url url = 'https://www.sogou.com/' # 2.发起请求,get的返回值是一个响应对象 response = requests.get(url) # 3.获取响应数据,text属性返回的是字符串形式的响应数据 page_text = response.text # 4.持久化存储 with open('./sogou.html','w',encoding='utf-8') as fp: fp.write(page_text)
-
需求:简易的网页采集器
url = 'https://www.sogou.com/web?query=人民币' response = requests.get(url) page_text = response.text with open('./人民币.html','w',encoding='utf-8') as fp: fp.write(page_text)
-
上述代码出现的问题:
- 出现了乱码
- 数据的量级不够
-
处理乱码
url = 'https://www.sogou.com/web?query=人民币' response = requests.get(url) # 修改响应数据的编码格式 response.encoding = 'utf-8' page_text = response.text with open('./人民币.html','w',encoding='utf-8') as fp: fp.write(page_text)
-
处理数据量级的问题:
- 遇到了对应的反爬机制
- 反爬机制:UA检测
- 反反爬策略:UA伪装
- UA伪装的实现:
- 1.定义一个字典
- 2.在字典中进行相关请求头信息的伪装
- 3.将该字典作用到get方法的headers参数中即可
- UA检测被作用到了大量的网站中,因此日后,爬虫程序编写中一定要直接加上UA的操作
url = 'https://www.sogou.com/web?query=人民币' headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36' } response = requests.get(url,headers=headers) # UA伪装 # 修改响应数据的编码格式 response.encoding = 'utf-8' page_text = response.text with open('./人民币.html','w',encoding='utf-8') as fp: fp.write(page_text)
-
最终实现
- 请求参数的动态化
- 实现:
- 1.定义一个字典
- 2.字典中的键值就是url携带的参数
- 3.将字典作用到get方法的params参数中
url = 'https://www.sogou.com/web' headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36' } # 参数动态化 wd = input('enter a key word:') param = { 'query':wd } response = requests.get(url,headers=headers,params=param) # UA伪装 # 修改响应数据的编码格式 response.encoding = 'utf-8' page_text = response.text fileName = wd+'.html' with open(fileName,'w',encoding='utf-8') as fp: fp.write(page_text) print(fileName,'爬取成功!!!')
-
-
需求:爬取豆瓣电影的详情数据
-
分析:
-
更多的电影数据是通过将滚轮滑动到底部后发起了ajax请求请求到的电影数据
-
对ajax请求的url进行捕获
-
对ajax请求的url进行请求发送
url = 'https://movie.douban.com/j/chart/top_list' fp = open('./movieData.txt','a+',encoding='utf-8') for i in range(0,10): param = { 'type': '13', 'interval_id': '100:90', 'action': '', 'start': str(i*20), 'limit': '20', } response = requests.get(url=url,params=param,headers=headers) # json()将json串进行序列化 movie_list = response.json() for dic in movie_list: name = dic['title'] score = dic['score'] fp.write(name+':'+score+' ') print('第{}页数据爬取成功!'.format(i)) fp.close()
-
-
需求:肯德基餐厅查询http://www.kfc.com.cn/kfccda/storelist/index.aspx
-
分析:
-
动态加载数据
-
动态加载数据
-
概念:通过其他/另一个请求请求到的数据
-
特性:可见非可得
-
判定相关的页面数据是否为动态加载的数据?
- 基于抓包工具定位到浏览器地址栏url对应的请求数据包,进行局部搜索:
- 搜索到:这组被搜索的数据不是动态加载的,可以直接爬取
- 没有搜到:这组数据是动态加载的,不可以直接爬取。
- 基于抓包工具定位到浏览器地址栏url对应的请求数据包,进行局部搜索:
-
如何捕获动态加载的数据?
基于抓包工具进行全局搜索,最终可以定位到动态加载数据对应的数据包。
import requests headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36' } data = { 'cname': '', 'pid': '', 'keyword': '广州', 'pageIndex': '1', 'pageSize': '10', } url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword' response = requests.post(url=url,headers=headers,data=data) pos_data = response.json() pos_data
-
-
药监总局数据爬取,爬取的是每一家企业的详情数据
-
分析:
-
打开了某一家企业的详情页面,看到了企业的详情数据
-
判定改家企业的详情数据是否为动态加载的?
- 进行局部搜索
- 没有搜索到,说明数据是动态加载出来的
- 捕获动态加载的数据?
- 全局搜索,定位到了动态加载数据对应的数据包,提取出了url和请求参数
- 进行局部搜索
-
成功的捕获到了一家企业对应的详情数据
-
通过上述方式继续分析第二家企业,发现:
-
捕获每一家企业的id
- 在首页中,通过抓包工具对企业名称进行搜索,对应的数据包中发现了企业名称和id
# 获取企业id ids = [] # 存储所有企业的id url = 'http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsList' for page in range(1,6): data = { 'on': 'true', 'page': str(page), 'pageSize': '15', 'productName': '', 'conditionType': '1', 'applyname': '', 'applysn': '', } company_datas_json = requests.post(url=url,headers=headers,data=data).json() for dic in company_datas_json['list']: _id = dic['ID'] ids.append(_id) detail_url = 'http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsById' for _id in ids: data = { 'id':_id } company_json = requests.post(url=detail_url,headers=headers,data=data).json() print(company_json['epsName'],company_json['epsProductAddress'])
-
总结:
- 很多网站都会设置UA反爬,一般爬取数据的时候都要加上UA伪造
- requests模块post请求与get请求的区别:
- 请求数据:post放在data的字典中,get放在params的字典中