参考 《Python 3网络爬虫开发实战 》崔庆才著
最基础的 HTTP 库有 urllib、httplib2、requests、treq
- 拿 urllib这个库来说,有了它,我们只需要关心请求的链接是什么,需要传的参数是什么,以及如何设置可选的请求头就好了,不用深人到底层去了解它到底是怎样传输和通信的。有了它,两行代码就可以完成一个请求和响应的处理过程,得到网页内容,是不是感觉方便极了?
urllib
官方文档链接为:https://docs.python.org/3/library/urllib.html
是 Python 置的 HTTP 请求库 ,也就是说不需要额外安装即可使用
包含如下四个模块
- request:它是最基本的HTTP请求模块,可以用来模拟发送请求。就像在浏览器里输入网址然后回车一样,只需要给库方法传入URL以及额外的参数,就可以模拟实现这个过程了。
同时它还带有处理授权验证( authentication )、重定向( redirection) 、浏览器 Cookies 及其他内容 - error:异常处理模块,如果出现请求错误,我们可以捕获这些异常,然后进行重试或其他操作以保证程序不会意外终止。
- parse:一个工具模块,提供了许多URL处理方法,比如拆分、解析、合并等。
- robotparser:主要是用来识别网站的 robots.txt文件,然后判断哪些网站可以爬,哪些网站不可以爬,它其实用得比较少。
请求模块
urlopen()
import urllib.request as re
response = re.urlopen('https://www.python.org')
print(response.read().decode('utf-8'))
这里我们只用了两行代码,便完成了 Python官网的抓取,输出了网页的源代码。得到源代码之后呢?我们想要的链接、图片地址、文本信息不就都可以提取出来了吗?
使用print(type(response))
得到的是
<class ‘http.client.HTTPResponse’>
可知返回的Response是一个HTTPResposne 类型的对象
可以发现,它是一个 HttpResponse类型的对象,主要包含read()
、 readinto()
、 getheader(name)
、getheaders()
、 fileno()
等方法,以及msg
、 version
、 status
(查看状态码)、 reason
、 debuglevel
、 closed
等属性。
urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None )
data
data参数是可选的。如果要添加该参数,并且如果它是字节流编码格式的内容,即 bytes类型,则需要通过 bytes()方法转化。另外,如果传递了这个参数,则它的请求方式就不再是GET方式,而是POST方式。
import urllib.request as re
import urllib.parse
data = bytes(urllib.parse.urlencode({'world': 'hello'}), encoding='utf8')
response = re.urlopen('http://httpbin.org/post', data=data)
print(response.read())
这里请求的站点是httpbin.org
,它可以提供HTTP请求测试。本次我们请求的URL为http://httpbin.org/post,这个链接可以用来测试POST请求,它可以输出请求的一些信息,其中包含我们传递的data参数。
httpbin 是一个使用 Python + Flask 编写的 HTTP HTTP Request & Response Service。该服务主要用于测试 HTTP 库。
你可以向他发送请求,然后他会按照指定的规则将你的请求返回。这个类似于echo服务器,但是功能又比它要更强大一些。 httpbin支持HTTP/HTTPS,支持所有的HTTP动词,能模拟302跳转乃至302跳转的次数,还可以返回一个HTML文件或一个XML文件或一个图片文件(还支持指定返回图片的格式)。
{
“args”: {},
“data”: “”,
“files”: {},
“form”: {
“world”: “hello”
},
“headers”: {
“Accept-Encoding”: “identity”,
“Content-Length”: “11”,
“Content-Type”: “application/x-www-form-urlencoded”,
“Host”: “httpbin.org”,
“User-Agent”: “Python-urllib/3.6”,
“X-Amzn-Trace-Id”: “Root=1-604b004e-5acf2c222196672a5f671b24”
},
“json”: null,
“origin”: “222.18.126.67”,
“url”: “http://httpbin.org/post”
}
我们传递的参数出现在了form字段中,这表明是模拟了表单提交的方式,以POST方式传输数据。
-
timeout参数
timeout参数用于设置超时时间,单位为秒,意思就是如果请求超出了设置的这个时间,还没有得到响应,就会抛出异常。如果不指定该参数,就会使用全局默认时间。它支持HTTP、Https、FTP请求。
因此,可以通过设置这个超时时间来控制一个网页如果长时间未响应,就跳过它的抓取。这可以利用 try except语句来实现,相关代码如下 -
其他参数
除了data参数和 timeout参数外,还有 context参数,它必须是ssl. SSLContext类型,用来指定SSL设置。
此外, cafile和 capath这两个参数分别指定CA证书和它的路径,这个在请求 Https链接时会有用。
Request
如果请求中需要加入 Headers等信息,就可以利用更强大的 Request类来构建。
Request型的对象。通过构造这个数据结构,一方面我们可以将请求独立成一个对象,另一方面可更加丰富和灵活地配置参数。
class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None
-
第一个参数url用于请求URL,这是必传参数,其他都是可选参数。
-
第二个参数data如果要传,必须传 bytes(字节流)类型的。如果它是字典,可以先用
urib. parse
模块里的urlencode()
编码。 -
第三个参数 headers是一个字典,它就是请求头,我们可以在构造请求时通过 headers参数直接构造,也可以通过调用请求实例的
add_header()
方法添加。
添加请求头最常用的用法就是通过修改User-Agent
来伪装浏览器,默认的User-Agent
是Python-urllib
,我们可以通过修改它来伪装浏览器。 -
第四个参数 origin_req_host指的是请求方的host名称或者IP地址。
-
第五个参数 unverifiable表示这个请求是否是无法验证的,默认是 False,意思就是说用户没有足够权限来选择接收这个请求的结果。例如,我们请求一个HTML文档中的图片,但是我们没有自动抓取图像的权限,这时 unverifiable的值就是True。
-
第六个参数 method是一个字符串,用来指示请求使用的方法,比如GET、POST和PUT等。
-
使用
import urllib.request as re import urllib.parse url = 'http://httpbin.org/post' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0', 'Host': 'httpbin.org' } dict = { 'name': 'hzq' } data = bytes(urllib.parse.urlencode(dict), encoding='utf8') req = re.Request(url=url, data=data, headers=headers, method='POST') response = re.urlopen(req) print(response.read().decode('utf-8'))
输出
{
“args”: {},
“data”: “”,
“files”: {},
“form”: {
“name”: “hzq”
},
“headers”: {
“Accept-Encoding”: “identity”,
“Content-Length”: “8”,
“Content-Type”: “application/x-www-form-urlencoded”,
“Host”: “httpbin.org”,
“User-Agent”: “Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0”,
“X-Amzn-Trace-Id”: “Root=1-604b1935-462a315809b49e2c7aadea2d”
},
“json”: null,
“origin”: “222.18.126.67”,
“url”: “http://httpbin.org/post”
}观察结果可以发现,我们成功设置了
data
headers
method
高级用法(强大的工具 Handler)
Cookies 处理、代理设置等操作…
首先,介绍一下urllib.request
模块里的 BaseHandler
类,它是所有其他 Handler的父类,它提供了最基本的方法,例如 default_open
()、 protocol_request()
等。
接下来,就有各种 Handler子类继承这个 BaseHandler类,举例如下。
-
HTTPDefaultErrorHandler
:用于处理HTTP响应错误,错误都会抛出HTTPError
类型的异常。 -
HTTPRedirectHandler
:用于处理重定向 -
HTTPCookieProcessOr
:用于处理 Cookies。 -
ProxyHandler
:用于设置代理,默认代理为空。 -
HTTPPasswordMgr
:用于管理密码,它维护了用户名和密码的表。 -
HTTPBasicAuthHandler
:用于管理认证,如果一个链接打开时需要认证,那么可以用它来解决认证问题。
另外,还有其他的 Handler类,这里就不一一列举了,详情可以参考官方文档:另一个比较重要的类就是
OpenerDirector
,我们可以称为Opener
。我们之前用过urlopen()
这个方法,实际上它就是ulib为我们提供的一个 Opener。
那么,为什么要引人 Opener呢?因为需要实现更高级的功能。之前使用的
Request
和urlopen()
相当于类库为你封装好了极其常用的请求方法,利用它们可以完成基本的请求,但是现在不一样了我们需要实现更高级的功能,所以需要深入一层进行配置,使用更底层的实例来完成操作,所以这里就用到了Opener
,Opener
可以使用open()
方法,返回的类型和urlopen()
如出一辙。那么,它和 Handler有什么关系呢?简而言之,就是利用 Handler来构建 Opener
-
验证
有些网站在打开时就会弹出提示框,直接提示你输入用户名和密码,验证成功后才能查看页面那么,如果要请求这样的页面,该怎么办呢?借助
HTTPBasicAuthHandler
就可以完成,相关代码from urllib.request import HTTPBasicAuthHandler, HTTPPasswordMgrWithDefaultRealm, build_opener from urllib.error import URLError username = 'name_hzq' password = 'password' url = 'http://localhost:5000/' p = HTTPPasswordMgrWithDefaultRealm() p.add_password(None, url, username, password) auth_handler = HTTPBasicAuthHandler(p) # 实例化对象,参数为p实例化对象,这样就建立了一个处理验证的Handler # 接下来,利用Handler并使用build_opener()方法构建一个Opener,这个Opener在发送请求时就相当于验证成功 opener = build_opener(auth_handler) try: result = opener.open(url) # 利用opener的open方法打卡链接,就可以完成验证 html = result.read().encode('utf-8') print(html) except URLError as e: print(e.reason)
-
代理
添加代理可以这样:from urllib.error import URLError from urllib.request import ProxyHandler, build_opener # 这里我们在本地搭建了一个代理,它运行在9743端口上。 # 这里使用了ProxyHandler,其参数是一个字典 # 键名是协议类型(比如HTTP或者Https等) # 值是代理链接,可以添加多个代理 proxy_handler = ProxyHandler({ 'http': 'http://127.0.0.1:9743', 'https': 'https://127.0.0.1:9743' }) # 利用这个Handler及build_opener()方法构造一个Opener opener = build_opener(proxy_handler) try: response = opener.open("https://www.baidu.com") print(response.read().encode('utf-8')) except URLError as e: print(e.reason)
-
Cookies
Cookies的处理需要相关的Handler
import http.cookiejar, urllib.request cookie = http.cookiejar.CookieJar() # 实例化一个CookieJar handle = urllib.request.HTTPCookieProcessor(cookie) opener = urllib.request.build_opener(handle) response = opener.open("http://www.baidu.com") for item in cookie: print(item.name+'='+item.value)
输出
BAIDUID=87E48F389921E784A456A90F0A53E72C:FG=1
BIDUPSID=87E48F389921E784FA0F94569587B39F
H_PS_PSSID=33514_33257_33344_31660_33691_33595_33570_33392_26350_33268
PSTM=1615536975
BDSVRTM=0
BD_HOME=1可以看到,这里输出了每条 Cookie的名称和值。
如果要将cookie保存到文件中(Mozilla类型文件)
import http.cookiejar, urllib.request cookie = http.cookiejar.MozillaCookieJar('CookiesTestSaveFilename.txt') # 是CookieJar的子类,可以用来处理Cookies和文件相关的事件,比如读取和保存 handle = urllib.request.HTTPCookieProcessor(cookie) opener = urllib.request.build_opener(handle) response = opener.open("http://www.baidu.com") cookie.save(ignore_discard=True, ignore_expires=True) for item in cookie: print(item.name+'='+item.value)
也可保存为LWP格式的文件
此时就使用
cookie = http.cookiejar.LWPCookiesJar(filename)
文件内容为
生成了cookie文件接下来就该读取和使用了
import http.cookiejar, urllib.request filename = 'CookiesTestSaveFilename.txt' cookie = http.cookiejar.LWPCookieJar() # 是CookieJar的子类,可以用来处理Cookies和文件相关的事件,比如读取和保存 # 注意为:cookies文件为LWP格式 cookie.load(filename, ignore_discard=True, ignore_expires=True) handle = urllib.request.HTTPCookieProcessor(cookie) opener = urllib.request.build_opener(handle) response = opener.open("http://www.baidu.com") print(response.read().decode('utf-8'))
-
如果想实现更多的功能,可以参考官方文档的说明https://docs.pythonorg/3/library/urllib.requesthtml#basehandler-objects
处理异常
urllib的 error模块定义了由 request模块产生的异常。如果出现了问题, request模块便会抛出error模块中定义的异常。
URLError
URLError类来自 urllib库的 error模块,它继承自OSError类,是eror异常模块的基类,由 request模块生的异常都可以通过捕获这个类来处理。
它具有一个属性 reason
,即返回错误的原因。
HTTPError
它是URLError的子类,专门用来处理HTTP请求错误,比如认证请求失败等。它有如下3个属性。
- code:返回HTTP状态码,比如404表示网页不存在,500表示服务器内部错误等。
- reason:同父类一样,用于返回错误的原因。
- headers:返回请求头。
解析链接(parse)
前面说过, urllib库里还提供了 parse
模块,它定义了处理URL的标准接口,例如实现URL各部分的抽取、合并以及链接转换。它支持如下协议的URL处理:file、ftp、 gopher、hdl、http、https、sftp、sip、sips、 snews、svn、swn+ssh、 telnet。本节中,我们介绍一下该模块中常用的方法来看一下它的便捷之处
urlparse
urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)
实现URL的识别和分段
-
unstring:这是必填项,即待解析的URL。
-
scheme:它是默认的协议(比如http或https等)。假如这个链接没有带协议信息,会将其作为协议信息
scheme参数只有在URL中不包含 scheme信息时才生效。如果URL中有 scheme信息,就会返回解析出的 scheme。
-
allow fragments:即是否忽略 fragment。如果它被设置为 False, fragment部分就会被忽略,它会被解析为path、 parameters或者 query的一部分,而 fragment部分为空。
import urllib.parse
result = urllib.parse.urlparse('http://www.baiducom/index.html;user?id=5#comment')
print(type(result), result)
<class ‘urllib.parse.ParseResult’>
ParseResult(scheme=‘http’, netloc=‘www.baiducom’, path=‘/index.html’, params=‘user’, query=‘id=5’, fragment=‘comment’)
可以看到,返回结果是一个 ParseResult类型的对象,它包含6个部分,分别是 scheme(协议)、 netloc(域名)、 path(访问路径)、 params(参数)、 query(查询条件)和 fragment(锚点,用于直接定位页面内部的下拉位置)
所以,可以得出一个标准的链接格式,具体如下scheme://netloc/path;params?query#fragment
urlunparse
有了 uniparse(),相应地就有了它的对立方法 urlunparse()实现URL的构造。它接受的参数是一个可迭代对象,但是它的长度必须是6,否则会抛出参数数量不足或者过多的问题。先用一个实例看一下
urlsplit
这个方法和 uniparse()方法非常相似,只不过它不再单独解析 params这一部分,只返回5个结果
urlunsplit
与 urlunparse()类似,它也是将链接各个部分组合成完整链接的方法,传人的参数也是一个可迭代对象,例如列表、元组等,唯一的区别是长度必须为5
urljoin
修了urlunparse()
和urlunsplit()
方法,我们可以完成链接的合并,不过前提必须要有特定长度象,链接的每一部分都要清晰分开。
此外,生成链接还有另一个方法,那就是urljoin()
方法。我们可以提供一个 base_url(基础链接)作为第一个参数,将新的链接作为第二个参数,该方法会分析 base_url的 scheme、 netloc和path这3个内容并对新链接缺失的部分进行补充,最后返回结果。
base_ur1提供三项内容 scheme、net1c和path。如果这3项在新的链接里不存在,就予以补充;如果新的链接存在,就使用新的链接的部分。而 base_url中的 params、 query和 fragment是不起作用的。
urlencode
在构造GET请求参数的时候非常有用
import urllib.parse as pa
params = {
'name': 'hzq',
'age': 22,
}
base_url = 'http://www.baidu.com?'
url = base_url + pa.urlencode(params)
print(url)
http://www.baidu.com?name=hzq&age=22
可以看到,参数就成功地由字典类型转化为GET请求参数了。
parse_qs
有了序列化,必然就有反序列化。如果我们有一串GET请求参数,利用 parse_qs()方法,就可将它转回字典,示例如下:
from urllib parse import parse_qs
query = 'name=hzq&age=22'
print(parse_qs(query))
{‘name’:[‘hzq’], ‘age’:[‘22’]}
parse_qsl
将参数转化为元组组成的列表,
from urllib parse import parse_qs
query = 'name=hzq&age=22'
print(parse_qsl(query))
[(‘name’, ‘hzq’),(’age’,'22’)]
可以看到,运行结果是一个列表,而列表中的每一个元素都是一个元组,元组的第一个内容是参数名,第二个内容是参数值
quote
该方法可以将内容转化为URL编码的格式。URL中带有中文参数时,有时可能会导致乱码的问题,此时用这个方法可以将中文字符转化为URL编码,示例如下
from urllib.parse import quote
keyword='壁纸'
url='https://www.baiducom/s?wd=' + quote(keyword)
print(url)
https://www.baidu.com/s?wd=%E5%A3%81%E7%BA%B8
unquote
有了 quote()方法,当然还有 unquote()方法,它可以进行URL解码,
分析Robots协议
利用 urllib的 robotparser模块,我们可以实现网站 Robots协议的分析。本节中,我们来简单了解一下该模块的用法。
Robots协议也称作爬虫协议、机器人协议,它的全名叫作网络爬虫排除标准( Robots exclusion Protocol),用来告诉爬虫和搜索引擎哪些页面可以抓取,哪些不可以抓取。它通常是一个叫作 robots.txt的文本文件,一般放在网站的根目录下。
当搜索爬虫访问一个站点时,它首先会检查这个站点根目录下是否存在 robots. txt文件,如果存在,搜索爬虫会根据其中定义的爬取范围来爬取。如果没有找到这个文件,搜索爬虫便会访问所有可直接访问的页面。robots.txt样例
User-agent: *
Disallow:/
Allow:/public/这实现了对所有搜索爬虫只允许爬取 public目录的功能,将上述内容保存成 robots txt文件,放在网站的根目录下,和网站的入口文件(比如 index. php、 index htm和 index. jsp等)放在一起。
上面的User-agent描述了搜索爬虫的名称,这里将其设置为*,代表该协议对任何爬取爬虫都有效
User-agent:Baiduspider
这就代表我们设置的规则对百度爬虫是有效的。如果有多条User-agent记录,则就会有多个爬虫会受到爬取限制,但至少需要指定一条。Disallow指定了不允许抓取的目录,比如上例子中设置为测则代表不允许抓取所有页面。
Allow一般和 Disallow一起使用,一般不会单独使用,用来排除某些限制。现在我们设置为/ public/,则表示所有页面不允许抓取,但可以抓取 public目录
爬虫名称
robotparse
了解 Robots协议之后,我们就可以使用 robotparser模块来解析 robots txt了。该模块提供了一个类 RobotFileParser
,它可以根据某网站的 robots. txt文件来判断一个爬取爬虫是否有权限来爬取这个网页。
该类用起来非常简单,只需要在构造方法里传入 robots. txt的链接即可。首先看一下它的声明
urllib.robotparser.RobotFileParser(url='')
当然,也可以在声明时不传入,默认为空,最后再使用 set_url()方法设置一下也可。
类的常用方法
- set_url():用来设置 robots. txt文件的链接。如果在创建 RobotFileParser对象时传入了链接,那么就不需要再使用这个方法设置了。
- read():读取 robots. txt文件并进行分析。注意,这个方法执行一个读取和分析操作,如果不调用这个方法,接下来的判断都会为 False,所以一定记得调用这个方法。这个方法不会返回任何内容,但是执行了读取操作
- parse():用来解析 robots. txt文件,传入的参数是 robots.txt某些行的内容,它会按照 robots.txt的语法规则来分析这些内容。
- can_fetch():该方法传入两个参数,第一个是
User-agent
,第二个是要抓取的URL
。返回的内容是该搜索引擎是否可以抓取这个URL,返回结果是True或 False。 - mtime():返回的是上次抓取和分析
robots.txt
的时间,这对于长时间分析和抓取的搜索爬虫是很有必要的,你可能需要定期检查来抓取最新的 robots.txt - modified():它同样对长时间分析和抓取的搜索爬虫很有帮助,将当前时间设置为上次抓取和分析 robots. txt的时间。
requests
属于第三方库, 需要使用pip安装。相比python自带的urllib,requests库对其进行了更方便的封装。
urllib库中的urlopen()方法实际上以GET方式请求网页,而requests中相应的方法就是get()
import requests
r = requests.get('http://www.baidu.com')
print(type(r)) # <class 'requests.models.Response'>
print(r.status_code) # 状态码
print(type(r.text)) # <class 'str'>
print(r.text) # html文档
print(r.cookies) # <RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>
其他的请求也可使用一句话实现
post()、put()、delete()、
GET
-
对于GET请求,如果要附加额外的信息,利用params参数
import requests data = { 'name': 'hzq', 'age': '22' } r = requests.get('http://httpbin.org/get', params=data) print(r.text)
网页的返回类型实际上是str类型,但是它很特殊,是JSON格式的。如果想要解析结果,得到一个字典格式的话,可以直接调用
json()
方法
调用json()方法,就可以将返回结果是JON格式的字符串转化为字典。
print(r.json())
但需要注意的是,如果返回结果不是JSON格式,便会出现解析错误,抛出json. decoder.350- ecodeError异常。
-
抓取网页
import requests import re header = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0' } r = requests.get("http://www.zhihu.com/explore", headers=header) pattern = re.compile('explore-feed.*?question_link.*?>(.*?)</a>', re.S) title = re.findall(pattern, r.text) print(title)
-
抓取二进制数据
图片、音频、视频这些文件本质上都是由二进制码组成的,由于有特定的保存格式和对应的解析方式,我们才可以看到这些形形色色的多媒体。所以,想要抓取它们,就要拿到它们的二进制码。
import requests headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0' } r = requests.get("https://www.baidu.com/favicon.ico", headers=headers) with open('favicon.ico', 'wb') as f: f.write(r.content) # 保存二进制到文件中
POST
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0'
}
data = {'name': 'hzq', 'age': '22'}
r = requests.post("http://httpbin.org/post", data,)
print(r.text)
高级用法
文件上传
在前一节中我们保存了一个文件 favicon.ico,这次用它来模拟文件上传的过程。需要注意的是, favicon. ico需要和当前脚本在同一目录下。如果有其他文件,当然也可以使用其他文件来上传,更改下代码即可。
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0'
}
files = {'file': open('favicon.ico', 'rb')}
r = requests.post("http://httpbin.org/post", files=files)
print(r.text)
结果:
里面包含 files这个字段,而form字段是空的,这证明文件上传部分会单独有一个 files字段来标识。
cookies
requests获取和设置 Cookies只需一步
r = requests.get("http://www.baidu.com")
print(r.cookies)
for key, value in r.cookies.items():
print(key, value)
这里我们首先调用 cookies属性即可成功得到 Cookies,可以发现它是 RequestCookieJar类型。
然后用 items()方法将其转化为元组组成的列表,遍历输出每一个 Cookie的名称和值,实现 Cookie的遍历解析。结果:
-
使用cookies维持登陆状态
将cookie复制到headers头部就可
-
会话维持
Session对象
s = requests.Session() s.get("http://httpbin.org/cookies/set/number2/23456") r = s.get("http://httpbin.org/cookies") print(r.text)
-
SSL证书验证
此外, requests还提供了证书验证的功能。当发送HTTP请求的时候,它会检查SSL证书,我们可以使用 verify参数控制是否检查此证书。其实如果不加 verify参数的话,默认是True,会自动验证
如果请求一个HTTPs站点,但是证书验证错误的页面时,就会报这样的错误SSLError,那么如何避免这个错误呢?很简单,把 verify参数设置为False即可。response= requests.get('url',verify=False)
-
代理设置
对于某些网站,在测试的时候请求几次,能正常获取内容。但是一旦开始大规模爬取,对于大规模且频繁的请求,网站可能会弹出验证码,或者跳转到登录认证页面,更甚者可能会直接封禁客户端的IP,导致一定时间段内无法访问。
这就需要用到 proxies参数。proxies = { 'http':'http://10.10.1.10:8888', 'https':'https://10.10.1.10:6666' } response = requests.get('url',proxies=proxies)
-
超时设置
在本机网络状况不好或者服务器网络响应太慢甚至无响应时,我们可能会等待特别久的时间才可能收到响应,甚至到最后收不到响应而报错。为了防止服务器不能及时响应,应该设置一个超时时间,即超过了这个时间还没有得到响应,那就报错。这需要用到 timeout参数。这个时间的计算是发出请求到服务器返回响应的时间。
response = requests.get('url',timeout=1) # 设置为1秒
如果想永久等待,可以直接将 timeout设置为None,或者不设置直接留空,因为默认是None。这样的话,如果服务器还在运行,但是响应特别慢,那就慢慢等吧,它永远不会返回超时错误的。
-
身份认证
import requests from requests.auth import HTTPBasicAuth response = requests.get('url', auth=HTTPBasicAuth('username', 'password'))
也可直接传一个元组
response = requests.get('url', auth=('username', 'password'))
它会默认使用 HttpbAsicAuth这个类来认证。
此外, requests还提供了其他认证方式,如 OAuth认证,不过此时需要安装 oauth包
-
Request对象
这里我们引入了 Request,然后用ur1、data和 headers参数构造了一个 Request对象,这时需要再调用 Session的 prepare request()方法将其转换为一个 Prepared Request.对象,然后调用send()方法发送即可
from requests import Request, Session s = Session() req = Request('POST', url='url',headers=headers,data=data) prepped = s.prepare_request(req) response = s.send() print(response.text)
有了 Request这个对象,就可以将请求当作独立的对象来看待,这样在进行队列调度时会非常方便。后面我们会用它来构造一个 Request队列。