GVKun编程网logo

python爬虫从入门到放弃(四)之 Requests库的基本使用

13

在本文中,您将会了解到关于python爬虫从入门到放弃的新资讯,同时我们还将为您解释四之Requests库的基本使用的相关在本文中,我们将带你探索python爬虫从入门到放弃的奥秘,分析四之Reque

在本文中,您将会了解到关于python爬虫从入门到放弃的新资讯,同时我们还将为您解释四之 Requests库的基本使用的相关在本文中,我们将带你探索python爬虫从入门到放弃的奥秘,分析四之 Requests库的基本使用的特点,并给出一些关于01 Python爬虫之Requests库入门、Jquery从入门到放弃(四)、Nginx 从入门到放弃(四)、Python 爬虫从入门到放弃(二十三)之 Scrapy 的中间件 Downloader Middleware 实现 User-Agent 随机切换的实用技巧。

本文目录一览:

python爬虫从入门到放弃(四)之 Requests库的基本使用

python爬虫从入门到放弃(四)之 Requests库的基本使用

原文地址https://www.cnblogs.com/zhaof/p/6915127.html

python爬虫从入门到放弃(四)之 Requests库的基本使用

 

什么是Requests

Requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库
如果你看过上篇文章关于urllib库的使用,你会发现,其实urllib还是非常不方便的,而Requests它会比urllib更加方便,可以节约我们大量的工作。(用了requests之后,你基本都不愿意用urllib了)一句话,requests是python实现的最简单易用的HTTP库,建议爬虫使用requests库。

默认安装好python之后,是没有安装requests模块的,需要单独通过pip安装

requests功能详解

总体功能的一个演示

复制代码
import requests

response  = requests.get("https://www.baidu.com")
print(type(response))
print(response.status_code)
print(type(response.text))
print(response.text)
print(response.cookies)
print(response.content)
print(response.content.decode("utf-8"))
复制代码

我们可以看出response使用起来确实非常方便,这里有个问题需要注意一下:
很多情况下的网站如果直接response.text会出现乱码的问题,所以这个使用response.content
这样返回的数据格式其实是二进制格式,然后通过decode()转换为utf-8,这样就解决了通过response.text直接返回显示乱码的问题.

请求发出后,Requests 会基于 HTTP 头部对响应的编码作出有根据的推测。当你访问 response.text 之时,Requests 会使用其推测的文本编码。你可以找出 Requests 使用了什么编码,并且能够使用 response.encoding 属性来改变它.如:

response =requests.get("http://www.baidu.com")
response.encoding="utf-8"
print(response.text)

不管是通过response.content.decode("utf-8)的方式还是通过response.encoding="utf-8"的方式都可以避免乱码的问题发生

各种请求方式

requests里提供个各种请求方式

复制代码
import requests
requests.post("http://httpbin.org/post")
requests.put("http://httpbin.org/put")
requests.delete("http://httpbin.org/delete")
requests.head("http://httpbin.org/get")
requests.options("http://httpbin.org/get")
复制代码

请求

基本GET请求

import requests

response = requests.get(''http://httpbin.org/get'')
print(response.text)

带参数的GET请求,例子1

import requests

response = requests.get("http://httpbin.org/get?name=zhaofan&age=23")
print(response.text)

如果我们想要在URL查询字符串传递数据,通常我们会通过httpbin.org/get?key=val方式传递。Requests模块允许使用params关键字传递参数,以一个字典来传递这些参数,例子如下:

复制代码
import requests
data = {
    "name":"zhaofan",
    "age":22
}
response = requests.get("http://httpbin.org/get",params=data)
print(response.url)
print(response.text)
复制代码

上述两种的结果是相同的,通过params参数传递一个字典内容,从而直接构造url
注意:第二种方式通过字典的方式的时候,如果字典中的参数为None则不会添加到url上

解析json

复制代码
import requests
import json

response = requests.get("http://httpbin.org/get")
print(type(response.text))
print(response.json())
print(json.loads(response.text))
print(type(response.json()))
复制代码

从结果可以看出requests里面集成的json其实就是执行了json.loads()方法,两者的结果是一样的

获取二进制数据

在上面提到了response.content,这样获取的数据是二进制数据,同样的这个方法也可以用于下载图片以及
视频资源

添加headers
和前面我们将urllib模块的时候一样,我们同样可以定制headers的信息,如当我们直接通过requests请求知乎网站的时候,默认是无法访问的

import requests
response =requests.get("https://www.zhihu.com")
print(response.text)

这样会得到如下的错误

 

 

 

复制代码
import requests
headers = {

    "User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"
}
response =requests.get("https://www.zhihu.com",headers=headers)

print(response.text)
复制代码

这样就可以正常的访问知乎了

基本POST请求

通过在发送post请求时添加一个data参数,这个data参数可以通过字典构造成,这样
对于发送post请求就非常方便

复制代码
import requests

data = {
    "name":"zhaofan",
    "age":23
}
response = requests.post("http://httpbin.org/post",data=data)
print(response.text)
复制代码

同样的在发送post请求的时候也可以和发送get请求一样通过headers参数传递一个字典类型的数据

响应

我们可以通过response获得很多属性,例子如下

复制代码
import requests

response = requests.get("http://www.baidu.com")
print(type(response.status_code),response.status_code)
print(type(response.headers),response.headers)
print(type(response.cookies),response.cookies)
print(type(response.url),response.url)
print(type(response.history),response.history)
复制代码

结果如下:

 

状态码判断
Requests还附带了一个内置的状态码查询对象
主要有如下内容:

100: (''continue'',),
101: (''switching_protocols'',),
102: (''processing'',),
103: (''checkpoint'',),
122: (''uri_too_long'', ''request_uri_too_long''),
200: (''ok'', ''okay'', ''all_ok'', ''all_okay'', ''all_good'', ''\o/'', ''✓''),
201: (''created'',),
202: (''accepted'',),
203: (''non_authoritative_info'', ''non_authoritative_information''),
204: (''no_content'',),
205: (''reset_content'', ''reset''),
206: (''partial_content'', ''partial''),
207: (''multi_status'', ''multiple_status'', ''multi_stati'', ''multiple_stati''),
208: (''already_reported'',),
226: (''im_used'',),

Redirection.
300: (''multiple_choices'',),
301: (''moved_permanently'', ''moved'', ''\o-''),
302: (''found'',),
303: (''see_other'', ''other''),
304: (''not_modified'',),
305: (''use_proxy'',),
306: (''switch_proxy'',),
307: (''temporary_redirect'', ''temporary_moved'', ''temporary''),
308: (''permanent_redirect'',
''resume_incomplete'', ''resume'',), # These 2 to be removed in 3.0

Client Error.
400: (''bad_request'', ''bad''),
401: (''unauthorized'',),
402: (''payment_required'', ''payment''),
403: (''forbidden'',),
404: (''not_found'', ''-o-''),
405: (''method_not_allowed'', ''not_allowed''),
406: (''not_acceptable'',),
407: (''proxy_authentication_required'', ''proxy_auth'', ''proxy_authentication''),
408: (''request_timeout'', ''timeout''),
409: (''conflict'',),
410: (''gone'',),
411: (''length_required'',),
412: (''precondition_failed'', ''precondition''),
413: (''request_entity_too_large'',),
414: (''request_uri_too_large'',),
415: (''unsupported_media_type'', ''unsupported_media'', ''media_type''),
416: (''requested_range_not_satisfiable'', ''requested_range'', ''range_not_satisfiable''),
417: (''expectation_failed'',),
418: (''im_a_teapot'', ''teapot'', ''i_am_a_teapot''),
421: (''misdirected_request'',),
422: (''unprocessable_entity'', ''unprocessable''),
423: (''locked'',),
424: (''failed_dependency'', ''dependency''),
425: (''unordered_collection'', ''unordered''),
426: (''upgrade_required'', ''upgrade''),
428: (''precondition_required'', ''precondition''),
429: (''too_many_requests'', ''too_many''),
431: (''header_fields_too_large'', ''fields_too_large''),
444: (''no_response'', ''none''),
449: (''retry_with'', ''retry''),
450: (''blocked_by_windows_parental_controls'', ''parental_controls''),
451: (''unavailable_for_legal_reasons'', ''legal_reasons''),
499: (''client_closed_request'',),

Server Error.
500: (''internal_server_error'', ''server_error'', ''/o\'', ''✗''),
501: (''not_implemented'',),
502: (''bad_gateway'',),
503: (''service_unavailable'', ''unavailable''),
504: (''gateway_timeout'',),
505: (''http_version_not_supported'', ''http_version''),
506: (''variant_also_negotiates'',),
507: (''insufficient_storage'',),
509: (''bandwidth_limit_exceeded'', ''bandwidth''),
510: (''not_extended'',),
511: (''network_authentication_required'', ''network_auth'', ''network_authentication''),

通过下面例子测试:(不过通常还是通过状态码判断更方便)

 

import requests

response= requests.get("http://www.baidu.com")
if response.status_code == requests.codes.ok:
    print("访问成功")

requests高级用法

文件上传

实现方法和其他参数类似,也是构造一个字典然后通过files参数传递

import requests
files= {"files":open("git.jpeg","rb")}
response = requests.post("http://httpbin.org/post",files=files)
print(response.text)

结果如下:

 

获取cookie

复制代码
import requests

response = requests.get("http://www.baidu.com")
print(response.cookies)

for key,value in response.cookies.items():
    print(key+"="+value)
复制代码

会话维持

cookie的一个作用就是可以用于模拟登陆,做会话维持

import requests
s = requests.Session()
s.get("http://httpbin.org/cookies/set/number/123456")
response = s.get("http://httpbin.org/cookies")
print(response.text)

这是正确的写法,而下面的写法则是错误的

import requests

requests.get("http://httpbin.org/cookies/set/number/123456")
response = requests.get("http://httpbin.org/cookies")
print(response.text)

因为这种方式是两次requests请求之间是独立的,而第一次则是通过创建一个session对象,两次请求都通过这个对象访问

证书验证

现在的很多网站都是https的方式访问,所以这个时候就涉及到证书的问题

import requests

response = requests.get("https:/www.12306.cn")
print(response.status_code)

默认的12306网站的证书是不合法的,这样就会提示如下错误

 

为了避免这种情况的发生可以通过verify=False
但是这样是可以访问到页面,但是会提示:
InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings InsecureRequestWarning)

解决方法为:

import requests
from requests.packages import urllib3
urllib3.disable_warnings()
response = requests.get("https://www.12306.cn",verify=False)
print(response.status_code)

这样就不会提示警告信息,当然也可以通过cert参数放入证书路径

代理设置

复制代码
import requests

proxies= {
    "http":"http://127.0.0.1:9999",
    "https":"http://127.0.0.1:8888"
}
response  = requests.get("https://www.baidu.com",proxies=proxies)
print(response.text)
复制代码

如果代理需要设置账户名和密码,只需要将字典更改为如下:
proxies = {
"http":"http://user:password@127.0.0.1:9999"
}
如果你的代理是通过sokces这种方式则需要pip install "requests[socks]"
proxies= {
"http":"socks5://127.0.0.1:9999",
"https":"sockes5://127.0.0.1:8888"
}

超时设置

通过timeout参数可以设置超时的时间

认证设置

如果碰到需要认证的网站可以通过requests.auth模块实现

复制代码
import requests

from requests.auth import HTTPBasicAuth

response = requests.get("http://120.27.34.24:9001/",auth=HTTPBasicAuth("user","123"))
print(response.status_code)
复制代码

当然这里还有一种方式

import requests

response = requests.get("http://120.27.34.24:9001/",auth=("user","123"))
print(response.status_code)

异常处理

关于reqeusts的异常在这里可以看到详细内容:
http://www.python-requests.org/en/master/api/#exceptions
所有的异常都是在requests.excepitons中

 

从源码我们可以看出RequestException继承IOError,
HTTPError,ConnectionError,Timeout继承RequestionException
ProxyError,SSLError继承ConnectionError
ReadTimeout继承Timeout异常
这里列举了一些常用的异常继承关系,详细的可以看:
http://cn.python-requests.org/zh_CN/latest/_modules/requests/exceptions.html#RequestException

通过下面的例子进行简单的演示

复制代码
import requests

from requests.exceptions import ReadTimeout,ConnectionError,RequestException


try:
    response = requests.get("http://httpbin.org/get",timout=0.1)
    print(response.status_code)
except ReadTimeout:
    print("timeout")
except ConnectionError:
    print("connection Error")
except RequestException:
    print("error")
复制代码

其实最后测试可以发现,首先被捕捉的异常是timeout,当把网络断掉的haul就会捕捉到ConnectionError,如果前面异常都没有捕捉到,最后也可以通过RequestExctption捕捉到

 

 

 

 

 

 

 

01 Python爬虫之Requests库入门

01 Python爬虫之Requests库入门

[TOC]

Requests库

Requests库的7个主要方法

方法 说明
requests.request() 构造一个请求,支撑以下各方法的基础方法
requests.get() 获取HTML网页的主要方法,对应于HTTP的GET
requests.head() 获取HTML网页头信息的方法,对应于HTTP的HEAD
requests.post() 向HTML网页提交POST请求的方法,对应于HTTP的POST
requests.put() 向HTML网页提交PUT请求的方法,对应于HTTP的PUT
requests.patch() 向HTML网页提交局部修改请求,对应于HTTP的PATCH
requests.delete() 向HTML页面提交删除请求,对应于HTTP的DELETE

Requests库的get()方法

  • r=requests.get(url)

    r:返回一个包含服务器资源的Response对象

    get:构造一个向服务器请求资源的Request对象

import requests	# 导入 requests库
r = requests.get("https://www.baidu.com")	# 使用get请求进行进行访问,得到response响应r
print(r.text)	# 打印response响应的文本内容

Requests库的head()方法

  • r=requests.head(url)

    r:返回一个包含服务器资源的Response对象

    **head:**构造一个向服务器获取HTML网页头信息的方法

# head方法
r = requests.head("https://www.baidu.com")  # 使用head请求进行访问
print(r.headers)    # 通过response响应中的headers打印 html中的头部信息
print(r.text)       # 通过text响应的文本内容无效

Response对象的属性

Response对象包含服务器返回的所有信息,也包含请求的Request信息

属性 说明
r.status_code HTTP请求的返回状态,200表示连接成功,404表示失败
r.text HTTP响应内容的字符串形式,即url对于的内容
r.encoding 从HTTP header中猜测的响应内容编码方式
r.apparent_encoding 从内容中分析出的响应内容编码方式(备选编码方式)
r.content HTTP响应内容的二进制形式

理解Requests库的异常

异常 说明
requests.ConnectionError 网络连接错误异常,如DNS查询失败、拒绝连接等
requests.HTTPError HTTP错误异常
requests.URLRequired URL缺失异常
requests.TooManyRedirects 超过最大重定向次数,产生重定向异常
requests.ConnectTimeout 连接远程服务器超时异常
requests.Timeout 请求URL超时,产生超时异常
r.raise_for_status() 如果不是200,产生异常requests.HTTPError

爬取网页的通用代码框架

import requests

def getHTMLText(url):
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status()	# 如果状态不是200,引发HTTPError异常
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return "产生异常"

HTTP协议

HTTP,Hypertext Transfer Protocol,超文本传输协议

HTTP是一个基于“请求与响应”模式的、无状态的应用层协议

HTTP协议采用URL作为定位网络资源的标识,URL格式如下:

http://host[:port][path]

**host:**合法的Internet主机域名或IP地址

**port:**端口号,缺省端口为80

**path:**请求资源的路径

协议对资源的操作

方法 说明
GET 请求获取URL位置的资源
HEAD 请求获取URL位置的资源的响应消息报告,即获得该资源的头部信息
POST 请求向URL位置的资源后附加新的数据
PUT 请求向URL位置存储一个资源,覆盖原URL位置的资源
PATCH 请求局部更新URL位置的资源,即改变该处资源的部分内容
DELETE 请求删除URL位置存储的资源

Http协议对资源的操作

理解PATCH和PUT的区别

假设URL位置有一组数据UserInfo,包括UserID、UserName等20个字段 **需求:**用户修改了UserName,其他不变

  • 采用PATCH,仅向URL提交UserInfo的局部更新请求
  • 采用PUT,必须将所有20个字段一并提交到URL,未提交字段被删除

PATCH的最主要好处:节省网络带宽

HTTP协议与Requests库

HTTP协议方法 Requests库方法 功能一致性
GET requests.get() 一致
HEAD requests.head() 一致
POST requests.post() 一致
PUT requests.put() 一致
PATCH requests.patch() 一致
DELETE requests.delete() 一致

Requests库主要方法解析

Requests库中有7个主要方法。其中,Requests库中最常使用的就是get和head方法

  • 1. requests.request(method, url, **kwargs)

    **method:**请求方式,对应get/put/post等7中

    **url:**拟获取页面的url链接

    **kwargs:控制访问的参数,13个。均为可选项

    1. params:字典或字节序列,作为参数增加到url中
    2. data:字典、字节序列或文件对象,作为Request的内容
    3. json:JSON格式的数据,作为Request的内容
    4. headers:字典,HTTP定制头
    5. cookies:字典或CookieJar,Request中的cookie
    6. auth:元组,支持HTTP认证功能
    7. files:字典类型,传输文件
    8. timeout:设定超时时间,秒为单位
    9. proxies:字典类型,设定访问代理服务器,可以增加登录认证
    10. allow_redirects:True/False,默认为True,重定向开关
    11. stream:True/False,默认为True,获取内容立即下载开关
    12. verify:True/False,默认为True,认证SSL证书开关
    13. cert:本地SSL证书路径
  • 2. requests.get(url, params=None, **kwargs)

    **url:**拟获取页面的url链接

    **params:**url中的额外参数,字典或字节流格式,可选

    **kwargs:控制访问的参数,12个。均为可选项(与上面内容一致,不再赘述)

  • 3. requests.head(url, **kwargs)

    **url:**拟获取页面的url链接

    **kwargs:控制访问的参数,13个。均为可选项(与上面内容一致,不再赘述)

  • 4. requests.post(url, data=None, json=None, **kwargs)

    **url:**拟更新页面的url链接

    **data:**字典、字节序列或文件,Request的内容

    **json:**JSON格式的数据,作为Request的内容

    **kwargs:控制访问的参数,11个。均为可选项(与上面内容一致,不再赘述)

  • 5. requests.put(url, data=None, **kwargs)

    **url:**拟更新页面的url链接

    **data:**字典、字节序列或文件对象,Request的内容

    **kwargs:控制访问的参数,12个。均为可选项(与上面内容一致,不再赘述)

  • 6. requests.patch(url, data=None, **kwargs)

    **url:**拟更新页面的url链接

    **data:**字典、字节序列或文件对象,Request的内容

    **kwargs:控制访问的参数,12个。均为可选项(与上面内容一致,不再赘述)

  • 7. requests.delete(url, **kwargs)

    **url:**拟删除页面的url链接

    **kwargs:控制访问的参数,13个。均为可选项(与上面内容一致,不再赘述)

Jquery从入门到放弃(四)

Jquery从入门到放弃(四)

jquery添加元素

  • append() - 在被选元素的结尾插入内容
  • prepend() - 在被选元素的开头插入内容
  • after() - 在被选元素之后插入内容
  • before() - 在被选元素之前插入内容

1.1插入元素

$("p").prepend("Some prepended text."); //基本方法

1.2三种办法

function appendText()
{
var txt1="<p>Text.</p>";               // 以 HTML 创建新元素
var txt2=$("<p></p>").text("Text.");   // 以 jQuery 创建新元素
var txt3=document.createElement("p");  // 以 DOM 创建新元素
txt3.innerHTML="Text.";
$("p").append(txt1,txt2,txt3);         // 追加新元素
}

删除元素

  • remove() - 删除被选元素(及其子元素)
  • empty() - 从被选元素中删除子元素

1   删除过滤

$("p").remove(".italic");  //过滤指定类的元素

Nginx 从入门到放弃(四)

Nginx 从入门到放弃(四)

前面我们学习了Nginx的基本操作和日志管理,今天我们学习一下生产环境经常会用到的路由定位location设置,在工作中,经常可能会出现怎么设置的路由访问不到网页呀?总是出现404错误啊,这些都很有可能是location的配置有误所导致的,所以学习location的配置也是学习Nginx必不可少的一节。

Nginx的location路由定位匹配

location是在server中匹配本地的目录,根据不同的url定位到不同的内容上。

 location [=|~|~*|^~] pattern {
     
 }
 # 中括号中不写任何参数表示一般匹配,也可以写参数
 # location = patt {} [精准匹配]
 # location patt {} [一般匹配]
 # location ~ patt {} [正则匹配]
# location ~* {} [正则匹配忽略大小写]
# location ^~ {} []

如何发挥作用呢?

首先查看是否有精准匹配,如果有,则停止匹配过程。

 location = patt {
    config A
 }

如果 $uri == patt, 匹配成功,使用 configA

 location = / {
    root /var/www/html
    index index.htm
 }
 location / {
    root /data/html
    index index.html
 }

上面配置如果访问http://xxx.com/

定位流程是

  1. 精确匹配中 “/” , 得到 index 页为 index.htm

  2. 再次访问 /index.htm,此次内部转跳uri已经是“/index.htm”,所以只能匹配中一般匹配

  3. 在/data/html中查找文件,访问路径是/data/html/index.htm

正则匹配

如果一般匹配能够匹配上,Nginx将继续查找是否有正则匹配能够匹配上,如果有就匹配正则匹配。正则匹配是比一般匹配优先的。

总结:location的命中过程

  1. 先判断精准命中,如果命中,立即返回结果并结束匹配过程

  2. 判断普通命中,如果有多个命中,记录下来最长的命中结果,但并不结束

  3. 继续判断正则表达式的匹配结果,按配置里的正则表达式顺序为准,由上到下开始匹配,一旦匹配成功1个,立即返回结果,结束匹配过程。

普通命中,顺序无所谓,是因为按命中的长短来确定的。

正则命中,顺序有所谓,因为是从前往后命中的。

Python 爬虫从入门到放弃(二十三)之 Scrapy 的中间件 Downloader Middleware 实现 User-Agent 随机切换

Python 爬虫从入门到放弃(二十三)之 Scrapy 的中间件 Downloader Middleware 实现 User-Agent 随机切换

原文地址 https://www.cnblogs.com/zhaof/p/7345856.html

总架构理解 Middleware

通过 scrapy 官网最新的架构图来理解:

 

 

这个图较之前的图顺序更加清晰,从图中我们可以看出,在 spiders 和 ENGINE 提及 ENGINE 和 DOWNLOADER 之间都可以设置中间件,两者是双向的,并且是可以设置多层.

关于 Downloader Middleware 我在 http://www.cnblogs.com/zhaof/p/7198407.html   这篇博客中已经写了详细的使用介绍。

如何实现随机更换 User-Agent

这里要做的是通过自己在 Downlaoder Middleware 中定义一个类来实现随机更换 User-Agent, 但是我们需要知道的是 scrapy 其实本身提供了一个 user-agent 这个我们在源码中可以看到如下图:

 

复制代码
from scrapy import signals
class UserAgentMiddleware(object):
    """This middleware allows spiders to override the user_agent"""

    def __init__(self, user_agent=''Scrapy''):
        self.user_agent = user_agent

    @classmethod
    def from_crawler(cls, crawler):
        o = cls(crawler.settings[''USER_AGENT''])
        crawler.signals.connect(o.spider_opened, signal=signals.spider_opened)
        return o

    def spider_opened(self, spider):
        self.user_agent = getattr(spider, ''user_agent'', self.user_agent)

    def process_request(self, request, spider):
        if self.user_agent:
            request.headers.setdefault(b''User-Agent'', self.user_agent)
复制代码

从源代码中可以知道,默认 scrapy 的 user_agent=‘Scrapy’, 并且这里在这个类里有一个类方法 from_crawler 会从 settings 里获取 USER_AGENT 这个配置,如果 settings 配置文件中没有配置,则会采用默认的 Scrapy,process_request 方法会在请求头中设置 User-Agent.

关于随机切换 User-Agent 的库

github 地址为:https://github.com/hellysmile/fake-useragent
安装:pip install fake-useragent

基本的使用例子:

复制代码
from fake_useragent import UserAgent

ua = UserAgent()

print(ua.ie)
print(ua.chrome)
print(ua.Firefox)
print(ua.random)
print(ua.random)
print(ua.random)
复制代码

这里可以获取我们想要的常用的 User-Agent, 并且这里提供了一个 random 方法可以直接随机获取,上述代码的结果为:

 

关于配置和代码

这里我找了一个之前写好的爬虫,然后实现随机更换 User-Agent,在 settings 配置文件如下:

复制代码
DOWNLOADER_MIDDLEWARES = {
    ''jobboleSpider.middlewares.RandomUserAgentMiddleware'': 543,
    ''scrapy.downloadermiddlewares.useragent.UserAgentMiddleware'': None,
}

RANDOM_UA_TYPE= ''random''
复制代码

这里我们要将系统的 UserAgent 中间件设置为 None,这样就不会启用,否则默认系统的这个中间会被启用
定义 RANDOM_UA_TYPE 这个是设置一个默认的值,如果这里不设置我们会在代码中进行设置,在 middleares.py 中添加如下代码:

复制代码
class RandomUserAgentMiddleware(object):
    ''''''
    随机更换User-Agent
    ''''''
    def __init__(self,crawler):
        super(RandomUserAgentMiddleware, self).__init__()
        self.ua = UserAgent()
        self.ua_type = crawler.settings.get(''RANDOM_UA_TYPE'',''random'')

    @classmethod
    def from_crawler(cls,crawler):
        return cls(crawler)

    def process_request(self,request,spider):

        def get_ua():
            return getattr(self.ua,self.ua_type)
        request.headers.setdefault(''User-Agent'',get_ua())
复制代码

上述代码的一个简单分析描述:
1. 通过 crawler.settings.get 来获取配置文件中的配置,如果没有配置则默认是 random,如果配置了 ie 或者 chrome 等就会获取到相应的配置
2. 在 process_request 方法中我们嵌套了一个 get_ua 方法,get_ua 其实就是为了执行 ua.ua_type,但是这里无法使用 self.ua.self.us_type,所以利用了 getattr 方法来直接获取,最后通过 request.heasers.setdefault 来设置 User-Agent

通过上面的配置我们就实现了每次请求随机更换 User-Agent

 

今天关于python爬虫从入门到放弃四之 Requests库的基本使用的讲解已经结束,谢谢您的阅读,如果想了解更多关于01 Python爬虫之Requests库入门、Jquery从入门到放弃(四)、Nginx 从入门到放弃(四)、Python 爬虫从入门到放弃(二十三)之 Scrapy 的中间件 Downloader Middleware 实现 User-Agent 随机切换的相关知识,请在本站搜索。

本文标签: