Requests包---官方文档
一. jupyter notebook工具的使用:
Anaconda:一款集成环境,集成的都是基于数据分析和机器学习的环境(模块).
jupyter Notebook:是anaconda提供的一款可视化的编码工具(基于浏览器的).
cmd启动jupyter notebook, 在哪里执行就是打开的当前根目录.
如果想用其他浏览器打开,就把域名复制下来,粘到其他浏览器即可. 可能需要password或者token,在cmd启动的时候会有一长串,粘进去即可.
打开的jupyter notebook左上角有个new,可以创建文件或者文件夹.
ipython notebook 对应ipynb,就是指jupyter创建的.
new python3就可以创建这个文件,后缀名自动生成.
创建完有两种,一个为code,一个为Markdown. 前者可运行,或者不可运行(是用来注释的).代码的话左边那个in不会消失,中括号里面的是第几行代码.
当前整个ipy文件相当于一块缓存,不分上下.
我完全可以这么写
print(a)
a = 10
最终是可以输出a=10的.
不管是code模式的cell,还是Markdown模式的,都是需要运行的.
快捷键:
添加一个cell: a或 b
删除cell:x 或 dd
双击:进入可编辑模式
切换cell模式:
y:markdown-->code
m:code-->Markdown
tab:
执行cell:shift+enter
打开帮助文档:shift+tab (查看使用案例等)
二. 爬虫基本知识的fiddle抓包工具的使用:
爬虫:就是通过编写程序模拟浏览器上网,然后让其去互联网上抓取数据的过程
特性:
模拟浏览器;抓取数据.
浏览器就是一款天然的爬虫工具.
爬虫的分类:
- 通用爬虫;(爬取一整张页面源码数据. 抓取系统(爬虫),经过处理后公开到检索接口)
- 聚焦爬虫;(爬取的是一张页面中局部的数据.(数据解析))
- 增量式爬虫.(用于监测网站数据更新的情况,从而爬取网站中最新更新出来的数据).
自己总结反爬机制和反反爬机制(自己总结)
反爬机制:对应的载体是网站.使用任何技术手段,阻止别人批量获取自己网站信息的一种方式。- 门户网站通过相应的策略和技术手段,防止爬虫程序进行网站数据的爬取。
反反爬策略:爬虫程序通过相应的策略和技术手段,破解门户网站的反爬虫手段,从而爬取到相应的数据。
两个反爬机制:
第一个反爬机制:
robots.txt协议:防君子不防小人. 只是给与的建议.
第二个反爬机制:
UA(User-Agent)识别.
fiddle使用:)(目的:安装https协议的证书,不安装的话是上不了网的.)
配置:tools--->options--->https--->capture ..下面的.那几个对勾勾上.
配置完连不上网怎么办?---到https那里,然后右边有个actions,首先要信任,选择第一个,然后再点击actions的第二个,把证书放到桌面,然后安装证书.
证书放在桌面上到将所有的证书放到下列存储,然后浏览放到受新人的根证书颁发机构,即可.
抓包工具本质上来说就是代理服务器.
http协议:就是客户端和服务端进行数据交互的形式.
常用的头信息:
User-Agent:请求载体的标识.
Connection:keep-alive
contnet-type:...
https:加密的http.
对称密钥加密.SSL加密技术.
非对称密钥加密.
证书密钥加密.https的证书机制.
三. requests模块的基本使用:
案例:
- 简易的网页采集器
- 爬取豆瓣/肯德基的相关数据
- 药监总局企业信息的爬取
requests:网络请求的模块,模拟浏览器发请求的.(安装包)
urllib只看下博客了解一下发起请求即可.
编码流程:
- 指定url.
- 发起了请求.
- 获取响应数据.
- 持久化存储.
爬取搜狗首页的页面源码数据.
#爬取搜狗首页的页面源码数据
import requests
# 1.指定url
url = 'https://www.sogou.com/'
# 2.发起请求:返回值是一个response
response = requests.get(url=url)
# 3.获取响应数据:text返回的字符串形式的响应数据(页面源码数据)
page_text = response.text
# 4.持久化存储
with open('sogou.html','w',encoding="utf-8") as f:
f.write(page_text)
简易的网页采集器
import requests
# 简易的网页采集器
url = 'https://www.sogou.com/web'
# 设定动态的请求参数
wd = input('enter a key word:')
params = {
'query':wd
}
# 参数2:params是一个字典,是用来处理动态请求参数
response = requests.get(url=url,params=params)
# 修改原始的响应数据的编码
response.encoding = 'utf8'
page_text = response.text
fileName = wd+'.html'
with open(fileName,'w',encoding='utf8') as f:
f.write(page_text)
print(fileName,"下载成功")
注意,如果抛出SSL异常,可能是因为开着fibble,进行拦截了.
第一个读取成功,第二个加载.
UA检测和动态参数处理.
需求:爬取ajax的内容(肯德基)(ajax的要在XHR里面看就行了)
jupyter notebook工具的使用:ajax是专门放到XHR的.
url="http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword'
"
city = input("enter a city name:")
# 该字典是用来处理封装post请求的请求参数
data= {
"cname":"",
"pid":"",
"keyword":city,
"pageIndex":"1",
"pageSize":'10',
}
requests.post(url=url,data=data,headers=headers)
response = requests.post(url=url,data=data,headers=headers)
json_data = response.json()
print(json_data)
爬虫步骤:
- 验证我们要爬取的数据是否为当前页面动态加载参数(另一个请求请求到的参数).
- 是:直接爬取不到.
- 不是:直接爬取到.
- 如何验证页面中的局部数据是否为动态加载呢?
- 首先在页面中赋值一部分的页面内容,然后再通过抓包工具定位到URL指定的数据包,在数据包的response中进行刚才复制内容的搜索,搜索到则表示没有动态加载,否则为动态加载.
总而言之,先判定是否加载验证.
步骤:
找url对应匹配的数据包.(1个数据包1个数据包找,看request url)
怎么全局搜索?
- 随便选择一个文件,然后按下ctrl+F,出现全局搜索框.找到一条查询结果.点击就是需要的内容.
问题:
- 用text保存出现文本怎么办?
--修改原始的响应数据的编码,一般改为response.encoding='utf8'即可.然后再写入response.text即可. - requests实例出来的text和content的区别?
--text返回的是unicode编码,content返回的是byte类型,二进制数据.
只要保存文本的话用text.
想要保存图片,文件等的话要用到content.
python中requests包的text和content方法的区别 - 怎么获得json数据?
--通过get或post方法,然后再json()即可.
h是召唤帮助文档.
四. 肯德基ajax信息返回:
通过content-type查看返回数据是json还是字符串,决定下面的情况.
把headers里面的url拿到手.
再拿request headers里面的form data的数据.这里总共5组数据.
text返回的是字符串,json返回的是json格式的数据类型.
# 注意,如果抛出下面异常,不一定是代码写错.可能是url地址错误.
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 2 column 1 (char 2)
总之,拿所有内容都从headers里面拿.
代码:
import requests
url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3719.400 QQBrowser/10.5.3715.400'
}
city = input('请输入你想查询的城市信息:')
form_data = {
'cname': '',
'pid': '',
'keyword': city,
'pageIndex': 1,
'pageSize': 100
}
r = requests.post(url=url, data=form_data, headers=headers) # post或者get是看这条数据是以什么样的形式传递的
print(r.json()) # 通过content-type判断是json类型还是string,前者用json,后者用text,content是传图片或文件的
五. 跳转详情页进行数据采集(二级页面)
问题:
values[i] = one_value.encode('latin-1')
UnicodeEncodeError: 'latin-1' codec can't encode character '\u2026' in position 30: ordinal not in range(256)
很有可能是因为User-Agent有省略号的问题...
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; W…) Gecko/20100101 Firefox/68.0'
我从火狐拿的就是这样,要注意了.
关于headers出现问题的情况
TypeError: not all arguments converted during string formatting
也就是说不能用%s咯?因为这里情况复杂,应当选择format.
错误代码:
son_url =
'http://125.35.6.84:81/xk/itownet/portal/dzpz.jsp?id=%s'
son_url = son_url%id
json.decoder.JSONDecodeError: Expecting value: line 4 column 1 (char 6)
python再错误.(实际上还是data的错误)
解决报错
然后仔细查看发现自己看到的只是表面,实际上它还是post请求.
注意,这里用火狐是没有找到的.我又切换回了谷歌,复制一下企业名,在network处按了ctrl+F粘贴进去定位到的.
完整代码:
import requests
# 母体
url = 'http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsList' # post方法
# 响应头是json数据类型
# 子体
# son_url = 'http://125.35.6.84:81/xk/itownet/portal/dzpz.jsp?id=a816739703564da7bd2838a0bb8007f1' # get方法
son_url = 'http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsById' # post方法
# 响应头是json数据类型
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3719.400 QQBrowser/10.5.3715.400'
}
for i in range(1,11):
form_data = {
'on': 'true',
'page': i,
'pageSize': 15,
'productName': '',
'conditionType': 1,
'applysn': ''
}
print(f'正在爬取第{i}页的数据')
r = requests.post(url=url, data=form_data, headers=headers)
json_data = r.json()
for data in json_data.get('list'):
id = data.get('ID')
son_data = {
'id': id
}
son_r = requests.post(url=son_url, data=son_data, headers=headers)
son_json_data = son_r.json()
print('法人:',son_json_data.get('businessPerson'),' ','公司:',son_json_data.get('epsName'))
# print(son_r.json())
# print(data.get('ID'))
注意,如果没有从html文件中查找到自己需要的局部数据,(那就说明是动态加载数据ajax传过来的,另一个心情求请求到的数据),按步骤一步一步来就可以的
操作步骤:
首先,分析数据是静态数据还是动态加载数据.
其次,选择爬取数据的格式.(如果是字符串用text,如果是json用json,全都用当前的headers的内容数据)
六. 对图片的保存
import requests
url = 'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=4096944214,1677787421&fm=26&gp=0.jpg'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'
}
r = requests.get(url=url,headers=headers)
data = r.content
with open('1.jpg','wb') as f:
f.write(data)
content是二进制数据格式.
七. 爬取豆瓣评分
完整代码:
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'
}
for i in range(16):
print(f'正在打印第{i+1}页的内容')
i = i * 20
params = {
'type': 5,
'interval_id': '100:90',
'action': '',
'start': i,
'limit': 20
}
url = f'https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&start={i}&limit=20'
r = requests.get(url=url,params=params,headers=headers)
data_lst = r.json()
for data in data_lst:
print('电影名:',data.get('title'),'观影人数:',data.get('vote_count'),'评分:',data.get('score'))
# print(r.text)
浙公网安备 33010602011771号