前言
回顾之前讲述了python语法编程 必修入门基础和网络编程,多线程/多进程/协程等方面的内容,后续讲到了数据库编程篇MySQL,Redis,MongoDB篇,和机器学习,全栈开发,数据分析前面没看的也不用往前翻,系列文已经整理好了:
1.跟我一起从零开始学python(一)编程语法必修
2.跟我一起从零开始学python(二)网络编程
3.跟我一起从零开始学python(三)多线程/多进程/协程
4.跟我一起从零开始学python(四)数据库编程:MySQL数据库
5.跟我一起从零开始学python(五)数据库编程:Redis数据库
6.跟我一起从零开始学python(六)数据库编程:MongoDB数据库
7.跟我一起从零开始学python(七)机器学习
8.跟我一起从零开始学python(八)全栈开发
9.跟我一起从零开始学python(九)数据分析
10.跟我一起从零开始学python(十)Hadoop从零开始入门
11.跟我一起从零开始学python(十一)简述spark
适用于零基础学习和进阶人群的python资源:
① 腾讯认证python完整项目实战教程笔记PDF
② 十几个大厂python面试专题PDF
③ python全套视频教程(零基础-高级进阶JS逆向)
④ 百个项目实战+源码+笔记
⑤ 编程语法-机器学习-全栈开发-数据分析-爬虫-APP逆向等全套项目+文档
本系列文根据以下学习路线展开讲述,由于内容较多,:
一丶采集功底专题
1.网络请求
网络请求是爬虫工程师采集数据的重要手段之一。在PC端爬虫中,网络请求通常使用HTTP协议进行通信,通过发送HTTP请求获取目标网站的数据。
爬虫工程师需要掌握HTTP协议的基本知识,包括HTTP请求和响应的格式、常见的HTTP请求方法(如GET、POST等)、HTTP请求头和响应头的常见字段等。
在进行网络请求时,爬虫工程师通常使用HTTP客户端库,如Python中的requests库、Java中的HttpClient等。这些库封装了HTTP协议的细节,提供了简单易用的API,方便爬虫工程师进行网络请求。
爬虫工程师还需要了解一些反爬虫技术,如User-Agent伪装、IP代理等,以应对目标网站的反爬虫策略。
一丶requests
1.requests源码解析
对于爬虫工程师来说,网络请求是常用的数据采集方式之一。而Python的requests库,作为一个高效且易用的HTTP请求库,被爬虫工程师广泛使用。在深入学习requests库前,建议先了解下其中的源码实现。
requests库是基于urllib3库封装的,所以在使用requests库时需要先安装对应的依赖库urllib3。
接下来,我们通过分析requests库的源代码,来了解其中的一些实现细节。
首先是发送请求的实现,即requests库中的Request类。Request类用于封装发送请求的参数,并通过一个Session对象发送请求并返回响应。以下是Request类的核心代码:
class Request:
@staticmethod
def send(session, method, url, **kwargs):
# ...
resp = session.request(method=method, url=url, **kwargs)
return resp
我们可以看到,Request类中的send方法调用了Session对象的request方法,这个方法是整个库中负责发送请求和返回响应的核心方法。以下是Session类中request方法的核心代码:
class Session:
def request(self, method, url, params=None, data=None, headers=None, cookies=None, files=None, auth=None,
timeout=None, allow_redirects=True, proxies=None, hooks=None, stream=None, verify=None, cert=None,
json=None):
# ...
return self.send(prep, **send_kwargs)
我们可以看到,Session对象的request方法的参数和关键字参数与HTTP请求的相关部分一一对应,其中最重要的是prep
参数(即经过预处理的Request
对象),它包含了请求的相关信息,如请求方法,请求头,请求体等。Session对象的request方法最终调用了self.send
方法,即发送HTTP请求并返回响应。
requests库实现了带有各种HTTP请求方法的函数接口,如requests.get()
、requests.post()
等,这些接口在内部会自动创建一个Session对象,然后调用Session对象的request方法,从而返回请求响应。
总体来说,requests是一个功能强大的HTTP请求库,它的源代码实现清晰、易于阅读和理解,掌握其中的实现细节可以帮助我们更好的使用这个库。
2.requests常用方法
requests是一个Python第三方库,用于发送HTTP请求。以下是requests常用方法:
-
requests.get(url, params=None, **kwargs)
:发送GET请求,url为请求的URL地址,params
为请求参数,kwargs
为其他可选参数。 -
requests.post(url, data=None, json=None, **kwargs)
:发送POST请求,url
为请求的URL地址,data
为请求数据,json
为请求的JSON
数据,**kwargs
为其他可选参数。 -
requests.put(url, data=None, **kwargs)
:发送PUT
请求,url
为请求的URL地址,data
为请求数据,**kwargs
为其他可选参数。 -
requests.delete(url, **kwargs)
:发送DELETE
请求,url
为请求的URL
地址,**kwargs
为其他可选参数。 -
requests.head(url, **kwargs)
:发送HEAD
请求,url
为请求的URL地址,**kwargs
为其他可选参数。 -
requests.options(url, **kwargs)
:发送OPTIONS
请求,url
为请求的URL
地址,**kwargs
为其他可选参数。 -
requests.request(method, url, **kwargs)
:发送自定义请求,method
为请求方法,url
为请求的URL
地址,**kwargs
为其他可选参数。 -
requests.session()
:创建一个Session
对象,用于保持会话状态。 -
requests.get(url, headers=headers)
:发送GET请求,并设置请求头。 -
requests.get(url, cookies=cookies)
:发送GET请求,并设置请求的Cookies
。 -
requests.get(url, proxies=proxies)
:发送GET请求,并设置代理服务器。 -
requests.get(url, timeout=timeout)
:发送GET请求,并设置超时时间。 -
requests.get(url, verify=verify)
:发送GET请求,并设置SSL证书验证。 -
requests.get(url, allow_redirects=allow_redirects)
:发送GET请求,并设置是否允许重定向。 -
requests.get(url, stream=stream)
:发送GET请求,并设置是否使用流式传输
3.data/json/param参数传递
在使用requests库发送网络请求时,我们可以通过传递不同的参数来实现不同的请求方式和数据传递方式。常用的参数包括data、json和params。
1.data参数
data参数用于传递表单数据,通常用于POST
请求。它可以是一个字典,也可以是一个字符串。如果是字典,requests
会自动将其转换为表单形式;如果是字符串,则需要手动指定Content-Type
为application/x-www-form-urlencoded
。
示例代码:
import requests
data = {
'username': 'admin',
'password': '123456'
}
response = requests.post('http://www.example.com/login', data=data)
2.json参数
json
参数用于传递JSON
格式的数据,通常用于POST
请求。它可以是一个字典,也可以是一个字符串。如果是字典,requests
会自动将其转换为JSON
格式;如果是字符串,则需要手动指定Content-Type
为application/json
。
示例代码:
import requests
data = {
'username': 'admin',
'password': '123456'
}
response = requests.post('http://www.example.com/login', json=data)
3.params参数
params
参数用于传递URL
参数,通常用于GET
请求。它可以是一个字典,也可以是一个字符串。如果是字典,requests
会自动将其转换为URL
参数;如果是字符串,则需要手动拼接URL
。
示例代码:
import requests
params = {
'page': 1,
'size': 10
}
response = requests.get('http://www.example.com/articles', params=params)
4.隧道代理使用
隧道代理是一种通过隧道连接到代理服务器的方式来进行网络请求的方法。这种方式可以帮助我们隐藏真实的IP地址,提高爬虫的稳定性和安全性。
使用隧道代理需要先购买代理服务,然后在代码中设置代理服务器的IP地址和端口号。以下是一个使用隧道代理的示例代码:
import requests
proxy = {
'http': 'http://代理服务器IP地址:端口号',
'https': 'https://代理服务器IP地址:端口号'
}
url = 'https://www.example.com'
response = requests.get(url, proxies=proxy)
print(response.text)
在上面的代码中,我们首先定义了一个代理字典,包含了http和https两种协议的代理服务器地址和端口号。然后使用requests
库的get
方法发送请求时,将代理字典作为proxies
参数传入即可。
需要注意的是,使用隧道代理可能会降低请求速度,而且代理服务的质量也会影响到爬虫的效果。因此,在选择代理服务时需要谨慎,建议选择稳定可靠的服务商。
5.证书异常处理
在进行网络请求时,有些网站会进行证书认证以确保数据的安全。如果requests库在进行SSL证书验证时遇到了问题,会抛出“证书验证异常(Certificate Verification Error)”的异常。这个异常通常是由于请求响应的SSL证书无效或不受信任导致的。
以下是requests库中处理证书异常的方法:
1.忽略证书验证
在使用requests库进行网络请求时,可以通过设置verify
参数为False
来忽略SSL证书验证。这个方法会禁止requests库对证书进行验证,而是采用不安全的方式进行通信,因此在进行敏感操作时应慎重使用。
例如:
response = requests.get('https://example.com', verify=False)
2.设置证书文件
可以通过设置cert
参数来指定一个证书文件,在请求时使用该证书进行验证。这个方法需要事先获得一个有效的证书文件,如果无法提供有效证书则无法进行安全通信。
例如:
response = requests.get('https://example.com', cert=('path/to/cert.crt', 'path/to/key'))
3.添加自定义证书
可以通过requests库提供的certifi
库在运行时初始化一个自定义证书,从而进行证书验证。这种方式需要提供证书的SHA256指纹值,并将其添加到requests库已有的证书列表中。
例如:
import certifi
cert = certifi.where()
fingerprints = {'example.com': 'A1:B2:C3:...', ...}
with open(cert, 'a') as f:
for host, fingerprint in fingerprints.items():
f.write(f'{host} {fingerprint}\n')
response = requests.get('https://example.com', verify=True)
在以上代码中,certifi.where()
用于获取当前Python环境中的证书路径,然后将每个需要验证的主机和其证书的SHA256指纹添加到证书文件中。
综上,要避免证书异常需要注意常见的安全规则,如设置SSL证书验证、使用CA颁发的证书、对外不开放不安全的通信端口等。需要快速扫描设备,确保组件升级到最新版本,在安全上下文中测试企业所依赖的所有服务并采用有力的加密技术以支持加密通信。
二丶httpx
1.httpx源码解析
httpx是一个Python异步HTTP客户端库,它提供了简单易用的API,支持异步和同步请求,支持HTTP/1.1和HTTP/2协议,支持代理、SSL/TLS、Cookie等功能。下面我们来看一下httpx的源码解析。
httpx的核心代码在client.py文件中,其中最重要的是Client类。Client类是httpx的主要接口,它提供了发送HTTP请求的方法,如get、post、put、delete等。下面是Client类的定义:
class Client:
def __init__(
self,
timeout=UNSET,
follow_redirects=UNSET,
max_redirects=UNSET,
verify=UNSET,
cert=UNSET,
trust_env=UNSET,
http2=UNSET,
backend=UNSET,
default_headers=UNSET,
base_url=UNSET,
app=UNSET,
auth=UNSET,
cookies=UNSET,
allow_redirects=UNSET,
proxies=UNSET,
dispatch=UNSET,
limits=UNSET,
pool_limits=UNSET,
retry=UNSET,
trust_env_proxies=UNSET,
headers=UNSET,
**extra_options,
):
...
Client类的构造函数接受很多参数,这些参数可以用来配置httpx的行为。其中比较重要的参数包括:
- timeout:请求超时时间。
- follow_redirects:是否自动跟随重定向。
- max_redirects:最大重定向次数。
- verify:是否验证SSL证书。
- cert:客户端证书。
- trust_env:是否信任环境变量。