zoukankan      html  css  js  c++  java
  • 7.代理handler

    简单的自定义opener()

    import urllib.request
    
    #构建一个HTTPHandler处理器对象,支持处理HTTP请求
    http_handler=urllib.request.HTTPHandler()
    
    #构建一个HTTPHandler处理器对象,支持处理HTTPS请求
    # http_handler=urllib.request.HTTPHandler()
    
    #调用urllib.request.build_opener()方法,创建支持处理HTTP请求的opener对象
    opener=urllib.request.build_opener(http_handler)
    
    #构建Request请求
    request=urllib.request.Request("http://www.baidu.com/")
    
    #调用自定义opener对象的open()方法,发送request请求
    response=opener.open(request)
    
    print(response.read().decode('utf-8'))

     

    ProxyHandler处理器(代理设置)

    使用代理IP,这是爬虫/反爬虫的第二大招,通常也是最好用的。

    很多网站会检测某一段时间某个IP的访问次数(通过流量统计,系统日志等),如果访问次数多的不像正常人,它会禁止这个IP的访问。

    所以我们可以设置一些代理服务器,每隔一段时间换一个代理,就算IP被禁止,依然可以换个IP继续爬取。

    import urllib.request
    
    # 构建了两个代理Handler,一个有代理IP,一个没有代理IP
    httpproxy_handler = urllib.request.ProxyHandler({"http": "120.26.110.59:8080"})
    nullproxy_handler = urllib.request.ProxyHandler({})
    
    proxySwitch = True #定义一个代理开关
    
    # 通过 urllib2.build_opener()方法使用这些代理Handler对象,创建自定义opener对象
    # 根据代理开关是否打开,使用不同的代理模式
    if proxySwitch:
        opener = urllib.request.build_opener(httpproxy_handler)
    else:
        opener = urllib.request.build_opener(nullproxy_handler)
    
    request = urllib.request.Request("http://www.baidu.com/")
    
    # 1. 如果这么写,只有使用opener.open()方法发送请求才使用自定义的代理,而urlopen()则不使用自定义代理。
    response = opener.open(request)
    
    # 2. 如果这么写,就是将opener应用到全局,之后所有的,不管是opener.open()还是urlopen() 发送请求,都将使用自定义代理。
    # urllib2.install_opener(opener)
    # response = urlopen(request)
    
    print(response.read().decode('utf-8'))

    如果代理IP足够多,就可以像随机获取User-Agent一样,随机选择一个代理去访问网站。

    import urllib.request
    import random
    
    #代理列表
    proxy_list = [
        {"http" : "124.88.67.81:80"},
        {"http": "120.26.110.59:8080"},
        {"http" : "124.88.67.81:80"},
        {"http" : "124.88.67.81:80"},
        {"http" : "124.88.67.81:80"}
    ]
    
    # 随机选择一个代理
    proxy = random.choice(proxy_list)
    # 使用选择的代理构建代理处理器对象
    httpproxy_handler = urllib.request.ProxyHandler(proxy)
    
    opener = urllib.request.build_opener(httpproxy_handler)
    
    request = urllib.request.Request("http://www.baidu.com/")
    response = opener.open(request)
    print(response.read().decode('utf-8'))

     

    HTTPPasswordMgrWithDefaultRealm()

    HTTPPasswordMgrWithDefaultRealm()类将创建一个密码管理对象,用来保存 HTTP 请求相关的用户名和密码,主要应用两个场景:

    1. 验证代理授权的用户名和密码 (ProxyBasicAuthHandler())
    2. 验证Web客户端的的用户名和密码 (HTTPBasicAuthHandler())

    ProxyBasicAuthHandler(代理授权验证)

    如果我们使用之前的代码来使用私密代理,会报 HTTP 407 错误,表示代理没有通过身份验证

    import urllib.request
    
    #私密代理授权的账户
    user="mr_mao_hacker"
    #私密代理授权的密码
    passwd="sffqry9r"
    #私密代理IP
    proxyserver="61.158.163.130:16816"
    
    #1.构建一个密码管理对象,用来保存需要处理的用户名和密码
    passwdmgr=urllib.request.HTTPPasswordMgrWithDefaultRealm()
    
    #2.添加账户信息,第一个参数realm是与远程服务器相关的域信息
    passwdmgr.add_password(None,proxyserver,user,passwd)
    
    #3.构建一个代理基础用户名/密码验证的ProxyBasicAuthHandler处理器对象,参数是创建的密码管理对象
    #   注意,这里不再使用普通ProxyHandler类了
    proxyauth_handler=urllib.request.ProxyBasicAuthHandler(passwdmgr)
    
    #4.通过build_opener()方法使用这些代理Handler对象,创建自定义opener对象,参数包括构建的 proxy_handler 和 proxyauth_handler
    opener=urllib.request.build_opener(proxyauth_handler)
    
    #5.构造Request请求
    request=urllib.request.Request("http://www.baidu.com/")
    
    #6.使用自定义opener发送请求
    response=opener.open(request)
    
    #7.打印响应内容
    print(response.read())

     

    Cookie原理

    HTTP是无状态的面向连接的协议, 为了保持连接状态, 引入了Cookie机制 Cookie是http消息头中的一种属性,包括:

    Cookie名字(Name)
    Cookie的值(Value)
    Cookie的过期时间(Expires/Max-Age)
    Cookie作用路径(Path)
    Cookie所在域名(Domain),
    使用Cookie进行安全连接(Secure)。
    
    前两个参数是Cookie应用的必要条件,另外,还包括Cookie大小(Size,不同浏览器对Cookie个数及大小限制是有差异的)。
    

    Cookie由变量名和值组成,根据 Netscape公司的规定,Cookie格式如下:

    Set-Cookie: NAME=VALUE;Expires=DATE;Path=PATH;Domain=DOMAIN_NAME;SECURE

    Cookie应用

    Cookies在爬虫方面最典型的应用是判定注册用户是否已经登录网站,用户可能会得到提示,是否在下一次进入此网站时保留用户信息以便简化登录手续。

    import urllib
    import urllib2
    import cookielib
    
    # 通过CookieJar()类构建一个cookieJar()对象,用来保存cookie的值
    cookie = cookielib.CookieJar()
    
    # 通过HTTPCookieProcessor()处理器类构建一个处理器对象,用来处理cookie
    # 参数就是构建的CookieJar()对象
    cookie_handler = urllib2.HTTPCookieProcessor(cookie)
    
    # 构建一个自定义的opener
    opener = urllib2.build_opener(cookie_handler)
    
    # 通过自定义opener的addheaders的参数,可以添加HTTP报头参数
    opener.addheaders = [("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36")]
    
    # renren网的登录接口
    url = "http://www.renren.com/PLogin.do"
    
    # 需要登录的账户密码
    data = {"email":"mr_mao_hacker@163.com", "password":"alarmchime"}
    
    # 通过urlencode()编码转换
    data = urllib.urlencode(data)
    
    # 第一次是post请求,发送登录需要的参数,获取cookie
    request = urllib2.Request(url, data = data)
    
    # 发送第一次的post请求,生成登录后的cookie(如果登录成功的话)
    response = opener.open(request)
    
    #print response.read()
    
    # 第二次可以是get请求,这个请求将保存生成cookie一并发到web服务器,服务器会验证cookie通过
    response_deng = opener.open("http://www.renren.com/410043129/profile")
    
    # 获取登录后才能访问的页面信息
    print response_deng.read()

     

    代理ip

    import requests
    
    #根据协议类型,选择不同的代理
    proxies={
        "http": "120.26.110.59:8080",
        "https": "http://12.34.56.79:9527",
    
    }
    
    response=requests.get("http://www.baidu.com",proxies=proxies)
    print(response.text)

     

    Requests: 让 HTTP 服务人类

    虽然Python的标准库中 urllib2 模块已经包含了平常我们使用的大多数功能,但是它的 API 使用起来让人感觉不太好,而 Requests 自称 “HTTP for Humans”,说明使用更简洁方便。

    Requests 唯一的一个非转基因的 Python HTTP 库,人类可以安全享用:)

    Requests 继承了urllib2的所有特性。Requests支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动确定响应内容的编码,支持国际化的 URL 和 POST 数据自动编码。

    requests 的底层实现其实就是 urllib3

    #requests 的底层实现其实就是 urllib3
    import requests
    response=requests.get("http://www.baidu.com/")
    print(response.text)

    Requests的文档非常完备,中文文档也相当不错。Requests能完全满足当前网络的需求,支持Python 2.6—3.5,而且能在PyPy下完美运行。

    import requests
    response=requests.get("https://www.baidu.com/",verify=True)
    
    print(response.text)

    requests模块post请求

    import requests
    import requests
    
    formdata = {
        "type":"AUTO",
        "i":"i love python",
        "doctype":"json",
        "xmlVersion":"1.8",
        "keyfrom":"fanyi.web",
        "ue":"UTF-8",
        "action":"FY_BY_ENTER",
        "typoResult":"true"
    }
    
    url = "http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=null"
    
    headers={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"}
    
    reponse=requests.post(url,data=formdata,headers=headers)
    print(reponse.text)
    
    #如果是json文件可以直接显示
    print(reponse.json())

    requests请求headers

    import requests
    kw={'wd':'长城'}
    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
    
    # params 接收一个字典或者字符串的查询参数,字典类型自动转换为url编码,不需要urlencode()
    response=requests.get("http://www.baidu.com/s?",params=kw,headers=headers)
    
    # 查看响应内容,response.text 返回的是Unicode格式的数据
    print(response.text)
    
    # 查看响应内容,response.content返回的字节流数据
    print(response.content)
    
    #查看完整url地址
    print(response.url)
    
    #查看响应头部字符编码
    print(response.encoding)
    
    #查看响应码
    print(response.status_code)

    requests模块私密代理

    import requests
    
    # 如果代理需要使用HTTP Basic Auth,可以使用下面这种格式:
    proxy={"http": "mr_mao_hacker:sffqry9r@61.158.163.130:16816"}
    
    response=requests.get("http://www.baidu.com", proxies = proxy)
    
    print(response.text)
    import requests
    
    auth=('test','123456')
    
    response=requests.get('http://192.168.199.107',auth=auth)
    
    print(response.text)

    爬取https网站

    import requests
    """
    如果SSL证书验证不通过,或者不信任服务器的安全证书,则会报出SSLError,
    据说 12306 证书是自己做的
    
    如果我们想跳过 12306 的证书验证,把 verify 设置为 False 就可以正常请求了
    
    """
    response = requests.get("https://www.12306.cn/mormhweb/",verify=False)
    print(response.text)
  • 相关阅读:
    Eclipse添加Android library错误的原因
    The primitive Java types
    TFS怎么查找一个用户提交的所有代码
    easyui tabs
    错误 CS0012 类型“xxx”在未引用的程序集中定义。必须添加对程序集“xxxx xxxxx”的引用
    Sql Server 列转逗号隔开的字符串 和 逆转
    DataTable程序分页 不推荐。
    EF执行存储过程并且返回DataSet
    EF运用成ADO.NET操作返回DataSet或者DataTable
    Sql 查询 表名 视图名称等
  • 原文地址:https://www.cnblogs.com/weihu/p/8988383.html
Copyright © 2011-2022 走看看