python爬虫之urllib(一)

Python 3 中的 urllib 库有四个模块,分别是urllib.requesturllib.errorurllib.parseurllib.robotparser。接下来我们对这四个模块做详细介绍       参考:https://docs.python.org/3/library/

一,urllib.request

    1.1 urllib.request.urlopen

              request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)

              参数含义:

               url:  打开一个url,url可以是一个字符串或者一个 Request 对象

               data:  参数必须是一个字节对象 ,该对象指明发送到服务器的附加数据。如果不需要发送数据,可以是None]

               timeout:  可选的参数 timeout 参数在秒的级别规定了一个连接尝试的阻塞等待时间(如果没有指定该参数,

                              全局的默认的超时时间将被启用),这个参数实际上只对http,https,ftp链接有效

               cafile和capath:  可选的 cafile 和 capath 参数用来为https请求指明一套可信的CA证书。cafile 必须是包含了

                                       一套证书的单独的文件,capath则应该指定这些证书文件的目录。

                                       ssl.SSLContext.load_verify_locations()函数中可以找到更多信息

                 context:  如果 context 参数被指定,它必须是一个带有各样SLL选项的ssl.SSLContext实例

                 cadefault:  参数已经被弃用,可以不用管了。

                 接下来让我看看怎么应用

                 我们使用 urllib.request.urlopen() 去请求百度贴吧,并获取到它页面的源代码。


import urllib.request 
url = "http://tieba.baidu.com" 
response = urllib.request.urlopen(url) 
html = response.read() # 获取到页面的源代码 
print(html.decode('utf-8')) # 转化为 utf-8 编码

                 设置请求超时,有些请求可能因为网络原因无法得到响应。因此,我们可以手动设置超时时间。

                  当请求超时,我们可以采取进一步措施,例如选择直接丢弃该请求或者再请求一次。

import urllib.request 
url = "http://tieba.baidu.com" 
response = urllib.request.urlopen(url, timeout=1) 
print(response.read().decode('utf-8'))

                   使用 data 参数提交数据,在请求某些网页时需要携带一些数据,我们就需要使用到 data 参数params 需要被转码成字节流。而 params 是一个字典。我们需要使用 urllib.parse.urlencode() 将字典转化为字符串。再使用 bytes() 转为字节流。最后使用 urlopen() 发起请求,请求是模拟用 POST 方式提交表单数据。

import urllib.parse
import urllib.request
url = "http://xx.xx.xx.xx/chitchat"
params = { "session":"1111","question":"你好" }
data = bytes(urllib.parse.urlencode(params), encoding='utf8')
response = urllib.request.urlopen(url, data=data)
print(response.read().decode('utf-8'))

     1.2 urllib.request.Request

由上我们知道利用 urlopen() 方法可以发起简单的请求。但这几个简单的参数并不足以构建一个完整的请求,如果请求中需要加入headers(请求头)、指定请求方式等信息,我们就可以利用更强大的Request类来构建一个请求。
按照国际惯例,先看下 Request 的构造方法:

urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)

  url: 参数是请求链接,这个是必传参数,其他的都是可选参数。

  data: 参数跟 urlopen() 中的 data 参数用法相同。

  headers: 参数是指定发起的 HTTP 请求的头部信息。headers 是一个字典。它除了在 Request 中添加,还可以

                        通过调用 Request实例的 add_header() 方法来添加请求头。

  origin_req_host: 参数指的是请求方的 host 名称或者 IP 地址。

  unverifiable: 参数表示这个请求是否是无法验证的,默认值是False。意思就是说用户没有足够权限来选择接收

                                 这个请求的结果。例如我们请求一个HTML文档中的图片,但是我们没有自动抓取图像的权限,

                                我们就要将 unverifiable 的值设置成 True。

   method: 参数指的是发起的 HTTP 请求的方式,有 GET、POST、DELETE、PUT等

      接下来看一个demo吧:

import urllib.parse
import urllib.request
url = 'https://fanyi.baidu.com/'
headers = {
    'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
}
values = {
    'from': 'zh',
    'to':'en',
    'query':'肥猪',
    'transtype':'translang',
    'simple_means_flag':'3'
}
data = urllib.parse.urlencode(values).encode("utf-8")
request = urllib.request.Request(url,data,headers)
response = urllib.request.urlopen(request).read().decode("utf-8")
print(response)

        1.3 urllib.request.install_opener(opener)

              urllib.request.build_opener([handler, ...])

      urllib.request.ProxyHandler(proxies=None)

             在抓取一个网站的信息时,如果我们进行频繁的访问,就很有可能被网站检测到而被屏蔽,解决这个问题的方法就是使用ip代理 。在我们接入因特网进行上网时,我们的电脑都会被分配一个全球唯一地ip地址供我们使用,而当我们频繁访问一个网站时,网站也正是因为发现同一个ip地址访问多次而进行屏蔽的,所以这时候如果我们使用多个ip地址进行随机地轮流访问,这样被网站检测的概率就很小了,这时候如果我们再使用多个不同的headers,这时候就有多个ip+主机的组合,访问时被发现率又进一步减小了

     步骤:

      1、ProxyHandler类可以使用ip代理访问网页

           proxy_support = urllib.request.ProxyHandler({}),其中参数是一个字典{‘类型’:'代理ip:端口号'}

      2、定制、创建一个opener

           opener = urllib.request.build_opener(proxy_support)

      3、安装opener

           urllib.request.install_opener(opener)

            调用默认的opener

            opener.open(url)

对于没有设置反爬虫机制的网站,我们只需要直接像上面那样引入ProxyHandler类进行处理,不需要考虑模仿浏览器

接下来看段例子:

import urllib.request
url="https://www.baidu.com"
for i in range(0,10000):
    html = urllib.request.urlopen(url)
    print(html.info())
    print(i)

上面程序行351行就出错了这是由于我们在访问的时候,网站会记下我们的ip,当我们的ip访问量在一段时间内超过网站设定的上限值的时候,这个请求就会被拒绝了

改进后代码:

#coding:utf-8
from urllib.request import Request
from urllib.request import urlopen
import urllib
import random

def gethtml(url,proxies):
    proxy = random.choice(proxies)
    proxy_support = urllib.request.ProxyHandler({"http":proxy})
    opener = urllib.request.build_opener(proxy_support)
    urllib.request.install_opener(opener)
    html = urlopen(url)
    return html
url = "https://www.baidu.com"
proxies=["101.53.101.172:9999","171.117.93.229:8118","119.251.60.37:21387","58.246.194.70:8080"]

for i in range(100):
    try:
        html = gethtml(url,proxies)
        print(html.info())
        print(i)
    except:
        print("故障")

        1.4 urllib.request.pathname2url(path)

              urllib.request.url2pathname(path)

                   暂还未研究透

         1.5  urllib.request.getproxies()

这个helper函数返回一个日程表dictionary 去代理服务器的URL映射。扫描指定的环境变量 _proxy大小写不敏感的方法,对所有的操作系统,当它不能找到它,从Mac OS X的Mac OSX系统配置和Windows系统注册表中寻找代理信息。如果两个大写和小写环境变量存在(或不一样),小写优先。

请注意,如果环境变量 REQUEST_METHOD已被设置,这通常表明你在CGI脚本运行环境,此时环境变量 HTTP_PROXY(大写 _PROXY)将被忽略。这是因为该变量可以被客户端使用注射“代理:”HTTP头。如果你需要使用一个HTTP代理在CGI环境中,要么使用 ProxyHandler明确,或者确保变量名小写(或至少是 _proxy后缀)。

          1.6  urllib.request.OpenerDirector

OpenerDirector类打开url并通过 BaseHandler连接在一起。它管理处理程序的连接,和恢复错误。

          1.7   urllib.request.BaseHandler

这是对于所有已注册的处理程序的基类

          1.8  urllib.request.HTTPRedirectHandler

一个类来处理重定向

          1.9  urllib.request.HTTPCookieProcessor(cookiejar=None)

一个类来处理HTTP cookie。

          1.10  urllib.request.HTTPPasswordMgr

保持一个数据库 (realm, uri) -> (user, password)映射。

         1.11  urllib.request.HTTPPasswordMgrWithDefaultRealm

保持一个数据库 (realm, uri) -> (user, password)映射。一个领域 None被认为是一个全方位领域,如果没有其他搜索领域

         1.12  urllib.request.HTTPPasswordMgrWithPriorAuth

一个变体 HTTPPasswordMgrWithDefaultRealm还有一个数据库 uri -> is_authenticated的映射。可以使用BasicAuth处理程序来确定当发送身份验证凭证立即而不是等待 401响应。

         1.13  urllib.request.AbstractBasicAuthHandler(password_mgr=None)

这是mixin类,帮助与HTTP身份验证,远程主机和代理。果有password_mgr,应该是兼容 HTTPPasswordMgr的。请参阅部分 HTTPPasswordMgr对象必须支持的接口信息。如果passwd_mgr还提供了 is_authenticated和 update_authenticated方法(见 HTTPPasswordMgrWithPriorAuth对象),然后处理程序将使用 is_authenticated结果对于一个给定的URI来决定是否发送请求的身份验证凭证。如果 is_authenticated返回 TrueURI,凭证发送。如果 is_authenticated是 False凭证不发送,然后如果 401收到响应请求发送身份验证凭证。如果身份验证成功, update_authenticated被称为设置 is_authenticated TrueURI,这样后续请求的URI或任何super-URIs将自动包括身份验证凭证。

在新的3.5版本:添加 is_authenticated支持。

        1.14  urllib.request.HTTPBasicAuthHandler(password_mgr=None)

与远程主机处理身份验证。如果有password_mgr,应该是兼容HTTPPasswordMgr的。请参阅部分 HTTPPasswordMgr对象必须支持的接口信息。HTTPBasicAuthHandler将提高 ValueError当面对一个错误的身份验证方案。

        1.15  urllib.request.ProxyBasicAuthHandler(password_mgr=None)

处理与代理身份的验证。如果有password_mgr,应该是兼容 HTTPPasswordMgr的。请参阅部分 HTTPPasswordMgr对象必须支持的接口信息。

       1.16  urllib.request.AbstractDigestAuthHandler(password_mgr=None)

这是mixin类,帮助与HTTP身份验证,远程主机和代理。password_mgr,如果有,应该是兼容的 HTTPPasswordMgr;请参阅部分 HTTPPasswordMgr对象必须支持的接口信息

       1.17  urllib.request.HTTPDigestAuthHandler(password_mgr=None)

与远程主机处理身份验证。如果有password_mgr,应该是兼容 HTTPPasswordMgr的;请参阅部分 HTTPPasswordMgr对象必须支持的接口信息。摘要式身份验证处理程序和基本身份验证处理器都是补充说,摘要式身份验证总是尝试第一次。如果主机返回一个40 x再次回应,它发送到基本身份验证处理程序来处理。这个处理程序方法将提高 ValueError当面对除了消化或基本身份验证方案。

3.3版本的变化:提高 ValueError不支持的身份验证方案。

      1.18  urllib.request.ProxyDigestAuthHandler(password_mgr=None)

处理与代理身份验证。如果有password_mgr,应该是兼容 HTTPPasswordMgr的;请参阅部分 HTTPPasswordMgr对象必须支持的接口信息

      1.19 urllib.request.HTTPHandler

一个类来处理HTTP url

     1.20  urllib.request.HTTPSHandler(debuglevel=0, context=None, check_hostname=None)

一个类来处理开放的HTTPS url。在context 文和check_hostname有相同的意义 http.client.HTTPSConnection.

3.2版本的变化:context and check_hostname被补充。

     1.21  urllib.request.FileHandler

打开本地文件

     1.22  urllib.request.DataHandler

开放数据的url

     1.23  urllib.request.FTPHandler

开放的FTP url

     1.24 urllib.request.CacheFTPHandler

打开FTP url,保持打开的FTP连接缓存来减少延迟

    1.25  urllib.request.UnknownHandler

全方位类处理未知的url。

    1.26 urllib.request.HTTPErrorProcessor

HTTP错误响应过程。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

aqiu12316

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值