Python网络爬虫--urllib

urllib库是Python内置的HTTP请求库,包含四个模块:

  • request:最基本的HTTP请求模块,可以用来模拟发送请求。
  • error:异常处理模块,包含request模块HTTP请求过程抛出的异常
  • parse:一个工具模块,提供了许多URL处理的方法,比如拆、解析、合并等
  • robotparser:主要用来识别网站的robot.txt文件,然后判断网站哪些部分可以爬取

发送请求

urllib.request.urlopen():  

urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
  • url:请求的网址,必选参数
  • data:可选参数,如果设定,则该请求为POST请求方法。data必须为字节流数据(可用内置函数bytes()方法转换为字节流),数据内容如果是字典,可以通过parse模块的urlencode()方法将其转换为url格式的字符串
  • timeout:可选参数,设置请求超时时间,单位为秒
  • cafile:可选参数,CA证书文件
  • capath:CA证书路径
  • cadefault:python3中已经弃用
  • context:可选参数,指定SSL设置,必须为ssl.SSLContext类型
import urllib.request
import urllib.parse

name = bytes(urllib.parse.urlencode({"name":"Jane"}),encoding = "utf-8")
response = urllib.request.urlopen("https://www.python.org",data = name,timeout = 1)

urllib.request.Request()

urllib.request.open()方法可以实现最基本的请求,但是该方法中只有几个参数,有时候不能满足我们的要求。因此我们可以通过urllib.request.Request()构建一个请求

Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
  • url:必选参数,请求的网址
  • data:可选参数,如果设定,则该请求为POST请求方法。data必须为字节流数据(可用内置函数bytes()方法转换为字节流),数据内容如果是字典,可以通过parse模块的urlencode()方法将其转换为url格式的字符串
  • headers:可选参数,请求头
  • origin_req_host:客户端主机名称或者IP地址
  • unverifiable:用户没有足够的权限接收这个请求的结果,默认为False,即我们有权限接收
  • method:请求方法
from urllib import request,parse

headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36",
    "accept-encoding":"gzip",
    "Cookie":"_ga=GA1.2.1498502246.1545274514"
    }
data = bytes(parse.urlencode({"Language":"Python"}),encoding = "utf-8")
my_request = request.Request("https://www.python.org",headers = headers,data = data,method = "POST")
response = request.urlopen(my_request)

handler和opener

常用的handler:

  • HTTPDefaultErrorHandler:用于处理HTTP响应错误,错误都会抛出HTTPError类型的异常
  • HTTPRedirectHandler:用于处理重定向
  • HTTPCookieProcessor:用于处理Cookies
  • ProxyHandler:用于设置代理,默认代理为空
  • HTTPPasswordMgr:用于管理密码,维护用户名与密码的表单
  • HTTPBasicAuthHandler:用于管理认证,如果打开一个连接需要认真,那么可以用它来解决认证的问题
  • HTTPHandler:用来用处URL

opener:

  • urllib.request.build_opener([handler...]):实例化一个opener,使用各种功能的处理器
  • urllib.request.install_opener(opener) :设定一个全局opener,即程序里所有的请求都调用该opener

自定义的一般步骤:

  1. 使用相关功能的Handle处理器,来创建特定功能的处理器对象
  2. 然后通过如request.build_opener()方法,来使用这些处理器对象,创建自定义opener对象
  3. 使用自定义的opener对象,调用其open()方法向服务器发送请求
from urllib import request
http_handler = request.HTTPHandler() # 实例化一个具有处理url功能的处理器
my_opener = request.build_opener(http_handler) # 创建一个能使用该处理器的opener,此时该opener就具备了处理url功能
response = my_opener.open("https://www.python.org")  
# 设置代理
from urllib import request
my_proxy = {"http":"120.76.55.49:8088"}
proxy_handler = request.ProxyHandler(my_proxy)
proxy_opener = request.build_opener(proxy_handler)
response = proxy_opener.open("https://www.python.org")

#如果有多个代理
from urllib import request
import random
my_proxies = [
  {"http" : "124.88.67.81:80"},
  {"http" : "124.88.67.81:80"}, 
  {"http" : "124.88.67.81:80"},
  {"http" : "124.88.67.81:80"}, 
  {"http" : "124.88.67.81:80"}
    ]
proxy = random.choice(my_proxies)
proxy_handler = request.ProxyHandler(proxy)
proxy_opener = request.build_opener(proxy_handler)
response = proxy_opener.open("https://www.python.org")

平时我们设置Cookies都是在输入账户、密码登录之后,然后在浏览器保存这些信息(Cookies),然后再去查看源码找到这个Cookies(抓包),然后将它加入到请求头,根据源码再构建的请求。

而用handler的话,对于python2来说可以用cookielib模块和urllib.request.HTTPCookieProcessor来处理,对于cookielib模块有四个对象。在python3中,替换为http.cookiejar库,四个子类,同python2四个对象相同:

  • CookieJar:管理HTTP cookie值、存储HTTP请求生成的cookie、向传出的HTTP请求添加cookie的对象。整个cookie都存储在内存中,对CookieJar实例进行垃圾回收后cookie也将丢失。
  • FileCookieJar:FileCookieJar(filename,delayload=None,policy=None):从CookieJar派生而来,用来创建FileCookieJar实例,检索cookie信息并将cookie存储到文件中。filename是存储cookie的文件名。delayload为True时支持延迟访问文件,即只有在需要时才读取文件或在文件中存储数据。
  • MozillaCookieJar:MozillaCookieJar(filename, delayload=None, policy=None):从FileCookieJar派生而来,创建与Mozilla浏览器 cookies.txt兼容的FileCookieJar实例
  • LWPCookieJar:LWPCookieJar(filename, delay=None, policy=None):从FileCookieJar派生而来,创建与libwww-perl标准的Set-Cookie3文件格式兼容的FileCookieJar实例。

python2中基本用法:

from urllib import request
import cookielib
cookiejar = cookielib.CookieJar() # 创建一个Cookiejar对象来保存cookie
cookie_handler = request.HTTPCookieProcessor(cookiejar) # 创建一个cookie处理器对象
my_opener = request.build_opener(cookie_handler) # 创建一个opener来使用这个处理器
response = my_opener.open("https://www.baidu.com")

python3中基本用法(CookieJar()):

from urllib import request
from http import cookiejar

my_cookiejar = cookiejar.CookieJar() # CookieJar()可以管理,储存HTTP请求生成的cookie,我们把这个保存的cookie实例化
my_cookiehandler = request.HTTPCookieProcessor(my_cookiejar) # 创建一个处理cookiejar的处理器,也就是处理器处理这个cookie
opener = request.build_opener(my_cookiehandler) # 创建一个opener,此时这个opener就包含了这个cookie
response = opener.open("https://www.baidu.com")

大多数情况我们使用CookieJar(),但是如果需要同本地文件进行交互(也就是从本地读取,或者在本地创建),那么可以使用MozillaCookieJar()和LWPCookieJar(),两者用法一样,只需要将MozillaCookieJar和LWPCookieJar名称互换

from urllib import request
from http import cookiejar
my_cookiejar = cookiejar.MozillaCookieJar(file) # 创建一个符合Mozilla浏览器标准的cookiejar对象,叫做my_cookiejar,此时它是一个对象,一个MozillaCookieJar实例化对象。file,即我们要创建的cookie文件的文件名字
my_cookiehandler = request.HTTPCookieProsessor(my_cookiejar) # 创建一个处理这个cookiejar实例的处理器对象
openr = request.build_opener(my_cookiehandler) # 创建一个opener,来使用这个处理器对象 
response = opener.open("https://www.baidu.com")
# sava()将这个实例化对象my_cookiejar包含的cookies信息,保存成本地文件,文件名之前已经确定了。另外,还可以通过load()方法从一个文件导入cookies
# save()方法中两个参数,ignore_discard:保存需要被丢弃的cookies;ignore_expires:保存过期的cookies
# 通过下面代码可以发现本地电脑中创建了一个名为cookie的文本文件
my_cookiejar.save(ignore_discard = True,ignore_expires = True)

对于某些网站需要输入账户、密码才能访问,此处我们可以用HTTPPasswordMgrWithDefaultReadlm(管理账户、密码)、HTTPBasicAuthHandler

from urllib import request
username = "Maria"
password = "123456"
np = request.HTTPPasswordMgrWithDefaultReadlm() # 创建一个账户密码管理器对象
np.add_password(username,password) # 账户密码管理器中加入账户密码
auth_handler = request.HTTPBasicAuthHandler(np) # 创建一个验证该账户密码的处理器对象
opener = request.build_opener(auth_handler)
response = opener.open("https://www.baidu.com")

异常

异常:urrlib库的error模块定义了由request模块产生的异常,如果request模块应用过程出现了问题,request模块便会抛出error模块定义的异常。即,error模块能捕获request模块使用过程中出现的问题,error模块主要有三类:

  • ContentTooShortError
  • HTTPError
  • URLError

urllib.error.URLError

当各种处理器(handler)运行出现问题的时候,一般是没有网络连接或者是无法连接服务器处理器会抛出异常。它是OSError的子类,它具有一个属性:reason

reason:这个错误的原因,它可以是一个字符信息或者是一个异常实

urllib.error.HTTPError

它是URLError的子类,这一种异常通常是连接服务器后,服务器响应出现问题,如返回错误信息或者重定向错误,网页验证错误等等。虽然它是一个异常,但是它也可以像非异常文件样的函数方法一样返回(像urlopen()方法返回值一样),这在处理外部HTTPError非常有用,比如 说验证请求错误。这个类包含三个属性:code、reason、headers

  code:HTTP状态码

  reason:通常是一个字符串信息,解释这个错误的原因

  headers:导致HTTPError的HTTP请求后服务器返回的HTTP响应的头部信息。

urllib.error.ContentTooShort

当urlretrieve()函数检测到下载的数据量小于预期(这个预期在头部信息,Content-Length给定)时,抛出该异常。其中,content属性储存着下载的(或删减过后的)数据

from urllib import request
from urllib import error
try:
    response = request.urlopen("https://www.sdkfjla.com")
except error.URLError as ue:
    print(ue.reson)
    print(ue)
except error.HTTPError as he:
    print(he.code)
    print(he.reason)
    print(he.headers)
    print(he)
except Exception as e:
    print(e)

猜你喜欢

转载自www.cnblogs.com/sakura-d/p/10813489.html