03 爬虫_基本库的使用

参考 《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()等方法,以及msgversionstatus(查看状态码)、 reasondebuglevelclosed等属性。

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-AgentPython-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呢?因为需要实现更高级的功能。之前使用的 Requesturlopen()
相当于类库为你封装好了极其常用的请求方法,利用它们可以完成基本的请求,但是现在不一样了我们需要实现更高级的功能,所以需要深入一层进行配置,使用更底层的实例来完成操作,所以这里就用到了 Opener, Opener可以使用open()方法,返回的类型和 urlopen()如出一辙。那么,它和 Handler有什么关系呢?简而言之,就是利用 Handler来构建 Opener

  • 验证
    有些网站在打开时就会弹出提示框,直接提示你输入用户名和密码,验证成功后才能查看页面

    image-20210312160136266那么,如果要请求这样的页面,该怎么办呢?借助 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)
    

    image-20210312162334944

    也可保存为LWP格式的文件
    此时就使用
    cookie = http.cookiejar.LWPCookiesJar(filename)
    文件内容为
    image-20210312162638742

    生成了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目录

爬虫名称

image-20210312180618502

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)

结果:
image-20210314211244066

里面包含 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的遍历解析。结果:

image-20210314211708093

  • 使用cookies维持登陆状态
    将cookie复制到headers头部就可
    image-20210314212954867

  • 会话维持

    Session对象

    s = requests.Session()
    s.get("http://httpbin.org/cookies/set/number2/23456")
    r = s.get("http://httpbin.org/cookies")
    print(r.text)
    

    image-20210314214518058

  • 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队列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值