bobdu.cc

Follow me on GitHub

urllib

urllib.request.urlopen() 函数

urlopen()用于实现对目标url的访问

函数原型

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

函数参数

url 目标资源在网络中的位置。

可以是

  1. 表示URL的字符串(如:http://www.xxxx.com/);
  2. 一个urllib.request对象

data 用来指明发往服务器请求中的额外的信息

(如:在线翻译,在线答题等提交的内容)。

  1. HTTP是python中实现的众多网络通信http、https、ftp等协议中,唯一一个 使用data 参数的,也就是说只有打开的是http网址的时候,自定义data参数才会有作用。(https不行吗???)
  2. data必须是一个字节数据对象(Python的bytes object)
  3. data必须符合标准the standard application/x-www-form-urlencoded format,怎么得到这种标准结构的data呢?使用urllib.parse.urlencode()将自定义的data转换成标准格式,而这个函数所能接收的参数类型是pyhon中的mapping object(键/值对,如dict) or a sequence of two-element tuples(元素是tuple的列表)。
  4. data也可以是一个可迭代的对象,这种情况下就需要配置response对象中的Conten-length,指明data的大小。
  5. data默认是None,此时以GET方式发送请求;当用户给出data参数的时候,改为POST方式发送请求。
  6. 在此处给出data与在实例化Request对象时给出效果一样,但此处给出的值会覆盖Request.data

cafile、capath、cadefault 用于实现可信任的CA证书的HTTP请求。

不推荐使用,建议改用context上下文

context参数:实现SSL加密传输。

必须是ssl.SSLContext描述各种SSL选项的实例

返回值

当URL是HTTP和HTTPS时,此函数返回稍微修改过的http.client.HTTPResponse对象。


urllib.request.Request() 类

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

headers

是一个字典,常用来伪装User-Agent


在urllib的基础上封装属于自己的爬虫库

"""对urllib库的进一步封装,便于爬虫的使用"""

__author__ = 'BobDu'

from urllib import parse
from urllib import request
from urllib.error import URLError, HTTPError
from http import cookiejar


class Session:
    """用于实现post登录后自动保存cookie,以及添加代理"""
    def __init__(self, proxy=None):
        # 设置请求会话cookie
        cookie = cookiejar.CookieJar()
        handler = request.HTTPCookieProcessor(cookie)
        self.opener = request.build_opener(handler)

        if proxy:
            # 如果提供了代理字典,则添加代理
            proxy_handler = request.ProxyHandler(proxy)
            self.opener.add_handler(proxy_handler)

    def get(self, url, headers=None):
        return get(url, headers=headers, opener=self.opener)

    def post(self, url, form, headers=None):
        return post(url, form, headers=headers, opener=self.opener)


def get(url, headers=None, opener=None):
    return urlrequest(url, headers=headers, opener=opener)


def post(url, form, headers=None, opener=None):
    return urlrequest(url, form, headers=headers, opener=opener)


def urlrequest(url, form=None, headers=None, opener=None):
    html_byte = b''

    data = None
    if form:
        form_str = parse.urlencode(form)
        data = form_str.encode('utf-8')

    user_agent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 ' \
                 '(KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
    _headers = {
        'User-Agent': user_agent
    }
    if headers:
        _headers.update(**headers)
        headers = _headers
    else:
        headers = _headers

    req = request.Request(url, data=data, headers=headers)

    try:
        if opener:
            response = opener.open(req, timeout=2)
        else:
            response = request.urlopen(req, timeout=2)
        html_byte = response.read()
    except HTTPError as e:
        print(e)
    except URLError as e:
        print(e)

    return html_byte


if __name__ == '__main__':
    url = 'https://www.bobdu.cc'
    url2 = 'http://www.xicidaili.com'
    html_byte = get(url2)
    print(html_byte)