目录
- 1、发送带headers的请求——模仿浏览器获取和浏览器一致的数据
- (1)什么是参数
- 注意:
- 2、练习——贴吧爬虫
- (1)回忆面向对象
- (2)回忆快速生成列表
- (3)代码及运行结果
- 3、requests模块发送post请求
- (1)回忆哪些地方会用到 POST 请求
- (2)用法
- (3)通过百度翻译的例子来看 post 请求如何使用
- 代码
- 结果
- 自定义输入
- 4、requests模块使用代理
- (1)为什么爬虫需要使用代理?
- (2)区别
- (3)用法:
- (4)分类
- (5)代码
- (6)注意
- 5、requests模拟登录的三种方式
- (1)cookie和session的区别
- (2)爬虫处理 cookie 和 session
- (3)处理 cookies session 请求
- (4)使用session来登录easy-mock(仅需账号密码就能登录而不需要拖动进度条或者图形验证码的网站)
- 使用 cookie 来登录easy-mock
- (5)不发送 post 请求,直接使用 cookie 获取登陆后的网站
- (6)cookie 作为 requests.get(cookies=) 的参数是字典——将字符串转化为字典 字典推导式
- (7)总结:获取登录后页面的三种方式
- 6、requests模块发送请求和获取网页字符串
- 1) requests 中解决编解码问题
- 2)response.content 和 response.text 的对比
- 7、requests 保存图片——二进制文件的保存
引入:
# 判断状态码
assert response.status_code==200
# 一些命令
response=requests.get(url,headers=headers)
response.headers
response.request.url
response.url
response.request.headers
1、发送带headers的请求——模仿浏览器获取和浏览器一致的数据
(1)什么是参数
eg http://www.baidu.com/s?wd=python&c=d
参数的形式:字典
kw={‘wd’:‘长城’}
用法 requesr.get(url,params=kw)
import requests
headers={'User-Agent':'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Mobile Safari/537.36'}
p={'wd':'python'}
r = requests.get('http://www.baidu.com/s?',headers=headers,params=p)
print(r.status_code)
print(r.request.url)
注意:
2、练习——贴吧爬虫
(1)回忆面向对象
(2)回忆快速生成列表
[i for i in range(3)]
[i+3 for i in range(3)]
(3)代码及运行结果
对比以下两端代码,应用面向对象思想的代码明显可读性要高很多
import requests
class TiebaSpider:
def __init__(self,tiebaname):#初始化
self.tiebaname=tiebaname
self.url_temp='http://tieba.baidu.com/f?kw='+tiebaname+'&ie=utf-8&pn={}'
self.headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36'}
def run(self):#主程序执行
# 1、制造 url 列表
url_list=[self.url_temp.format(i*50) for i in range(50)]
# 2、遍历、发送请求、获取响应
for url in url_list:
print(url)
r = requests.get(url,headers=self.headers)
c = r.content.decode()
# 3、保存
filepath = '{}-第{}页'.format(self.tiebaname,url_list.index(url)+1)# 李毅-第1页......
with open(filepath,'w',encoding='utf-8') as f:
f.write(c)
if __name__=='__main__':
tieba = TiebaSpider('李毅')
tieba.run()
import requests
class TiebaSpider:
def __init__(self,tiebaname):
self.tiebaname=tiebaname
self.headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36'}
self.url_temp='http://tieba.baidu.com/f?kw='+tiebaname+'&ie=utf-8&pn={}'
def get_url_list(self):# 构造 Url 列表
return [self.url_temp.format(50*i) for i in range(10)]
def parse_url(self,url):# 发起请求,返回响应
r = requests.get(url,headers=self.headers)
return r.content.decode()
def save(self,html_str,page_num):
filepath='{}吧-第{}页.html'.format(self.tiebaname,page_num)# lol吧-第1页。html
with open(filepath,"w",encoding='utf-8') as f:
f.write(html_str)
def run(self):
# 1、构造 Url 列表
url_lists=self.get_url_list()
# 2、遍历、发起请求、获得响应
for url in url_lists:
html_str = self.parse_url(url)
# 3、保存
page_num = url_lists.index(url)+1
self.save(html_str,page_num)
if __name__=='__main__':
tieba = TiebaSpider('lol')
tieba.run()
这里仅展示部分:
爬取的html中有大量被注释掉的部分——原因:网页的源代码也被注释掉了
为什么源代码被注释掉,在原网页依然正常显示:利用js将注释符号去掉
列表推导式
[self.url_temp.format(50*i) for i in range(10)]
3、requests模块发送post请求
requests 深入
发送 post 请求
使用代理
处理 cookies session
(1)回忆哪些地方会用到 POST 请求
- 登陆注册
- 需要传输大文本
(2)用法
r = requests.post('url',data=data,headers=headers)
data的形式:字典
(3)通过百度翻译的例子来看 post 请求如何使用
参考文档:链接: 百度翻译开发者文档
1
2
3
- 使用 pycharm 小技巧——重新格式化代码来美化代码,提高代码的可读性
- 使用 pycharm 小技巧 光标跳到行首或者行尾快捷键:
Ctrl + 左方括号 快速跳到代码开头
Ctrl + 右方括号 快速跳到代码末尾
代码
# -*- coding: utf-8 -*-
# This code shows an example of text translation from English to Simplified-Chinese.
# This code runs on Python 2.7.x and Python 3.x.
# You may install `requests` to run this code: pip install requests
# Please refer to `https://api.fanyi.baidu.com/doc/21` for complete api document
import requests
import random
import json
from hashlib import md5
# Set your own appid/appkey.
appid = '20240604002069765'
appkey = 'FYj6ztBmjGCjXlfQ8FdM'
from_lang = 'auto'
to_lang = 'zh'
endpoint = 'http://api.fanyi.baidu.com'
path = '/api/trans/vip/translate'
url = endpoint + path
query = 'Hello World! This is 1st paragraph.\nThis is 2nd paragraph.'
# Generate salt and sign-----salt:随机数 可为字母或数字的字符串--------sign:签名 appid+q+salt+密钥的MD5值
def make_md5(s, encoding='utf-8'):
return md5(s.encode(encoding)).hexdigest()
salt = random.randint(32768, 65536)
sign = make_md5(appid + query + str(salt) + appkey)
# Build request
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
payload = {'appid': appid, 'q': query, 'from': from_lang, 'to': to_lang, 'salt': salt, 'sign': sign}
# Send request
r = requests.post(url, params=payload, headers=headers)
result = r.json()
# Show response
print(json.dumps(result, indent=4, ensure_ascii=False))
#json.dumps():这是 Python json 模块中的一个函数,用于将 Python 对象(通常是字典或列表)转换为 JSON 格式的字符串
res=[i['dst'] for i in result["trans_result"]]
print(res)
结果
自定义输入
query=input()
from_lang = ‘auto’
to_lang = ‘en’
4、requests模块使用代理
(1)为什么爬虫需要使用代理?
- 让服务器以为不是同一个客户端在请求
- 防止我们的真实地址被泄露,防止被追究
(2)区别
浏览器知道服务器的信息:正向代理(vpn访问google服务器)
不知道服务器的信息:反向代理(django nginx)
(3)用法:
requests.get("http://www.baidu.com", proxies = proxies)
#proxies的形式:字典
(4)分类
透明、高匿、普匿
(5)代码
# https://www.kuaidaili.com/free/intr
import requests
proxies={'http':'http://8.220.204.215:8008'}
headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36'}
r = requests.get('http://www.baidu.com',proxies=proxies,headers=headers)
print(r.status_code) #200
(6)注意
- 准备一堆ip地址,组成ip池,随机选择一个ip来使用
- 如何随机选择代理ip,让使用次数较少的Ip地址有更大的可能性被用到
(1){“ip”:ip,“times” :0}
(2)[{},{},{},{},{}}],对这个ip的列表进行排序,按照使用次数进行排序
(3)选择使用次数较少的10个ip,从中随机选择一 - 检查ip的可用性
(1)可以使用requests添加超时参数,判断ip地址的质量
(2)在线代理ip质量检测的网站
5、requests模拟登录的三种方式
(1)cookie和session的区别
- cookie数据存放在客户的浏览器上,session数据放在服务器上
- cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗。
- session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
- 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
(2)爬虫处理 cookie 和 session
- 带上cookie、session的好处
能够请求到登录之后的页面 - 带上cookie、session的弊端
一套cookie和session往往和一个用户对应请求太快,请求次数太多,容易被服务器识别为爬虫 - 不需要cookie的时候尽量不去使用cookie
但是为了获取登录之后的页面,我们必须发送带有cookies的请求
(3)处理 cookies session 请求
requests 提供了一个叫做session类,来实现客户端和服务端的会话保持
使用方法:
1.实例化一个session对象
2让session发送get或者post请求
session=requests.session()
response=session.get(url,headers
使用requests提供的session类来请求登录之后的网站的思路:
- 实例化session
- 先使用session发送请求,登录网站,把cookie保存在session中
- 再使用session请求登陆之后才能访问的网站,session能够自动的携带登录成功时保存在其中的cookie,进行请求
(4)使用session来登录easy-mock(仅需账号密码就能登录而不需要拖动进度条或者图形验证码的网站)
import requests
s = requests.session()
post_url='https://mock.presstime.cn/login'
post_data={'name':'damon','password':'wy062600'}
headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36'}
# 使用session发送post请求,cookie保存在其中
s.post(post_url,data=post_data,headers=headers)
#在使用session进行请求登录后才能访问的地址
r=s.get('https://mock.presstime.cn/',headers=headers)
#保存页面
with open('1.html','w',encoding='utf-8') as f:
f.write(r.content.decode())
说明:post_data查看方式:
代码运行结果:保存文件结果和个人主页源代码一致
使用 cookie 来登录easy-mock
import requests
# 将 cookie 放在 headers 中
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
'cookie':'easy-mock_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY3NDllNDRkODNlZTAxMTEzMmJjMjQzYyIsImlhdCI6MTczMjg5NTgyMSwiZXhwIjoxNzM0MTA1NDIxfQ.WaO8C8Hl2bQ1ISSQFqiVBu-C0T1k1vNI_b_qigBJ-6o',
}
# 利用requests.get 获取主页内容
r=requests.get('https://mock.presstime.cn/',headers=headers)
#保存页面
with open('2.html','w',encoding='utf-8') as f:
f.write(r.content.decode())
运行结果同上
- 直接带 cookie 可以使得代码更简洁
(5)不发送 post 请求,直接使用 cookie 获取登陆后的网站
- cookie 过期时间很长的网站
- 在 cookie 过期之前能够拿到所有的数据 比较麻烦
- 配合其他工具一起使用,其他程序专门获取 cookie ,当前程序专门请求页面
(6)cookie 作为 requests.get(cookies=) 的参数是字典——将字符串转化为字典 字典推导式
cookies='a=1; b=2; c=3'
cookies={i.split('=')[0]:i.split('=')[1] for i in cookies.split('; ')}
print(cookies)
(7)总结:获取登录后页面的三种方式
- 实例化session,使用session发送post请求,再使用他获取登陆后的页面
- headers中添加cookie键,值为cookie字符串
- 在请求方法中添加cookies参数,接收字典形式的cookie。字典形式的cookie中的键是cookie的name对应的值,值是cookie的value对应的值
6、requests模块发送请求和获取网页字符串
import requests
r = requests.get('http://www.baidu.com')
print(r.status_code)
print(r.encoding) # utf-8
print(r.text) # response属性一般是名词,方法一般是动词
print(r.content) # bytes类型通过decode()进行解码
print(r.content.decode()) # 默认 utf-8 进行解码
1) requests 中解决编解码问题
response.content.decode() # 推荐
response.content.decode('gbk')
response.text
2)response.content 和 response.text 的对比
response.text
- 类型:str
- 解码类型:根据HTTP 头部对响应的编码作出有根据的推测,推测的文本编码
- 如何修改编码方式:response.encoding=‘gbk’
response.content
- 类型:bytes
- 解码类型: 没有指定
- 如何修改编码方式:response.content.deocde(“utf8”)
推荐 response.content.decode() : 因为用 response.text 修改编解码要些两行代码
7、requests 保存图片——二进制文件的保存
import requests
r = requests.get('https://requests.readthedocs.io/en/latest/_static/requests-sidebar.png')
with open('a.png','wb') as f:
f.write(r.content)
- 保存方式是 wb 的原因:wb 表示以 bytes 二进制类型保存,而 w 表示以 str 字符串的类型保存,图片(视频等二进制文件)只有以二进制的方式保存才能显示出来
- r.content 是二进制内容