zoukankan      html  css  js  c++  java
  • 学习笔记-Python-爬虫1-urllib、chardet

    # 爬虫
    - 两大特征
    - 按作者要求下载数据或者内容
    - 能自动在网络上流窜
    - 三大步骤
    - 下载网页
    - 提取正确的信息
    - 根据一定规则自动跳转到另外的网页上执行
    - 爬虫分类
    - 通用爬虫
    - 专用爬虫(聚焦爬虫)
    - Python网络包简介
    - Python2.x:urllib, urllib2, urllib3, httplib, httplib2, requests
    - Python3.x:urllib, urllib3, httplib2, requests
    - Python2:urllib和urllib2配合使用,或者requests
    - Python3:urllib, requests
    - urllib
    - 包含模块
    - urllib.request:打开和读取url
    - urllib.error:包含urllib.requests产生的常见的错误,使用try捕捉
    - urllib.parse:包含解析url方法(字典性的数据作为参数使用)
    - urllib.robotparse:解析robots.txt文件
    - 案例v1
    - 网页编码问题解决
    - chardet:可以自动检测页面文件的编码格式,但是,可能有误
    - 需要先安装:conda install chardet
    - 案例v2
    - urlopen的返回对象
    - 案例v3
    - geturl:返回请求对象的url
    - info:请求反馈对象的meta信息
    - getcode:返回的http code
    - request.data的使用
    - 访问网络的两种方法
    - get
    - 利用参数给服务器传递信息
    - 参数为dict格式,然后用parse编码
    - 案例v4
    - post
    - 一般向服务器传递参数使用
    - post是把信息自动加密处理
    - 我们如果想使用post方式传递信息,需要用到data参数
    - 使用post意味着Http的请求头可能需要更改:
    - Content-Type:application/x-www.form-urlencode
    - Content-Length:数据长度
    - 简而言之,一旦更改请求方法,请注意其他请求头部信息相适应
    - urllib.parse.urlencode可以将字符串自动转换成上面的
    - 案例v5
    - 为了更多的设置请求信息,单纯的通过urlopen已经不太好用了
    - 需要利用request.Request类
    - 案例v6
    - urllib.error
    - URLError产生原因:
    - 没网
    - 服务器链接失败
    - 找不到指定服务器
    - 本身是OSError的子类
    - 案例v7
    - HTTPError是URLError的一个子类
    - 案例v8
    - 两者区别:
    - HTTPError是对应的HTTP请求的返回码错误,如果返回错误码是400以上,则引发HTTPError
    - URLError对应的一般是网络出现问题,包括url错误
    - 关系区别:OSError-URLError-HTTPError
    - UserAgent
    - UserAgent:用户代理,简称UA,属于headers的一部分,服务器通过UA来判断访问者的身份
    - 常见的UA值,使用的时候可以直接复制粘贴,也可以用浏览器访问的时候抓包
    - 目前有Android、Firefox、Google Chrome、ios的UA
    - 这个是例子:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36
    - 设置UA可以通过两种方式
    - headers
    - add_header
    - 案例v9
    - ProxyHandler处理(代理服务器)
    - 使用代理IP,是爬虫的常用手段
    - 获取代理服务器的地址
    - www.xicidaili.com
    - www.goubanjia.com
    - 代理用来隐藏真实访问地址,代理也不允许频繁访问某一个固定网站,所以,代理一定要很多很多
    - 基本使用步骤:
    1、设置代理地址
    2、创建ProxyHandler
    3、创建Opener
    4、安装Opener
    - 案例v10
    - cookie & session
    - 由于http协议的无状态性(无记忆性),人们为了弥补这个缺憾,所采用的一个补充协议
    - cookie是发给用户(即http浏览器)的一段信息;session是保存在服务器上的对应另一半的信息,用来记录用户信息
    - cookie和session区别:
    - 存放位置不用
    - cookie不安全
    - session会保存在服务器上一定时间,会过期
    - 单个cookie保存数据不超过4K,很多浏览器限制一个站点最多保存20个
    - session的存放位置
    - 存在服务器端
    - 一般情况,session是放在内存中或者数据库中
    - 没有cookie登陆,案例v11,可以看到,没使用cookie则反馈网页未登陆
    - 使用cookie登陆
    - 直接把cookie复制下来,然后手动放入请求头,案例v12
    - http模块包含一些关于cookie的模块,通过他们我们可以自动使用cookie
    - CookieJar
    - 管理存储cookie,向传出的http请求添加cookie
    - cookie存储在内存中,CookieJar实例回收后cookie将消息
    - FileCookieJar(filename, delayload=None, policy=None)
    - 使用文件管理cookie
    - filename是保存cookie的文件
    - MozillaCookieJar(filename, delayload=None, policy=None)
    - 创建与mozilla浏览器cookie.txt兼容的fileCookieJar实例
    - LwpCookieJar(filename, delayload=None, policy=None)
    - 创建与libwww-perl标准兼容的Set-Cookie3格式的FileCookieJar实例
    - 他们之间的关系是CookieJar-->FileCookieJar-->MozillaCookie & LwpCookieJar
    - 利用cookieJar访问妙味课堂,案例v13
    - 自动使用cookie登陆,大致流程是:
    1、打开登陆页面后自动通过用户名和密码登陆
    2、自动提取反馈回来的cookie
    3、利用提取的cookie登陆
    - handler是Handler的实例,常用参看案例代码如下:
    - 用来处理复杂请求
    # 生成cookie管理器
    cookie_handler = request.HTTPCookieProcessor(cookie)
    # 生成http请求管理器
    http_handler = request.HTTPHandler()
    # 生成https管理器
    https_handler = request.HTTPSHandler()
    - 创建handler后,使用opener打开,打开后相应的业务由相应的handler处理
    - cookie作为一个变量,打印出来,案例v14
    - cookie的常见属性
    - name:名称
    - value:值
    - domain:可以访问此cookie的域名
    - path:可以访问的cookie页面路径
    - expires:过期时间
    - size:大小
    - Http字段
    - cookie的保存-FileCookieJar 案例v15
    - cookie的读取,案例v16

    '''
    案例v5
    利用parse模块模拟post请求
    以下是分析百度词典的步骤:
    1、打开F12
    2、尝试输入girl单词,每次敲一个字母后都有请求
    3、请求地址是https://fanyi.baidu.com/sug
    4、利用Network-sug-Headers,查看发现Form Data的值是kw:girl
    5、检查返回内容格式,根据返回头Response Headers下的Content-Type:application/json发现返回的是json格式内容,需要用到json包
    '''
    from urllib import request, parse
    import json
    
    '''
    大致流程是:
    1、利用data构造内容,然后urlopen()打开
    2、返回一个json格式结果
    3、结果就应该是girl的释义
    '''
    baseurl = 'https://fanyi.baidu.com/sug'
    # 存放用来模拟form的数据一定是dict格式
    data = {
        # girl是翻译输入的英文内容,应该由用户输入,此处使用硬编码
        'kw':'girl'
    }
    # 需要使用parse模块对data编码得到str类型,但是要用bytes格式才能传递,所以用encode()编码
    data = parse.urlencode(data).encode()
    print(type(data))
    # 我们需要构造一个请求头,请求头部应该至少包含传入的数据的长度
    # request要求传入的请求头是一个dict格式
    headers = {
        # 因为使用post,所以至少包含Content-Length字段
        'Content-Length':len(data)
    }
    # 有了headers, data, url就可以尝试发出请求
    rsp = request.urlopen(baseurl, data=data)
    # 读取返回内容,然后对内容进行解码,但下面解码失败了
    json_data = rsp.read().decode('utf-8')
    print(type(json_data))
    print(json_data)
    
    # 把json字符串转换成字典
    json_data = json.loads(json_data)
    print(type(json_data))
    print(json_data)
    for item in json_data['data']:
        print(item['k'],'---',item['v'])
    '''
    案例v6
    利用parse模块模拟post请求
    利用Request构造请求信息实例
    以下是分析百度词典的步骤:
    1、打开F12
    2、尝试输入girl单词,每次敲一个字母后都有请求
    3、请求地址是https://fanyi.baidu.com/sug
    4、利用Network-sug-Headers,查看发现Form Data的值是kw:girl
    5、检查返回内容格式,根据返回头Response Headers下的Content-Type:application/json发现返回的是json格式内容,需要用到json包
    '''
    from urllib import request, parse
    import json
    
    '''
    大致流程是:
    1、利用data构造内容,然后urlopen()打开
    2、返回一个json格式结果
    3、结果就应该是girl的释义
    '''
    baseurl = 'https://fanyi.baidu.com/sug'
    # 存放用来模拟form的数据一定是dict格式
    data = {
        # girl是翻译输入的英文内容,应该由用户输入,此处使用硬编码
        'kw':'girl'
    }
    # 需要使用parse模块对data编码得到str类型,但是要用bytes格式才能传递,所以用encode()编码
    data = parse.urlencode(data).encode()
    print(type(data))
    # 我们需要构造一个请求头,请求头部应该至少包含传入的数据的长度
    # request要求传入的请求头是一个dict格式
    headers = {
        # 因为使用post,所以至少包含Content-Length字段
        'Content-Length':len(data)
    }
    # 构造一个Request实例,用来设置请求头各种信息
    req = request.Request(baseurl, data, headers)
    # 因为已经构造了一个Request的请求实例,则可以直接传入urlopen中
    rsp = request.urlopen(req)
    # 读取返回内容,然后对内容进行解码,但下面解码失败了
    json_data = rsp.read().decode('utf-8')
    print(type(json_data))
    print(json_data)
    
    # 把json字符串转换成字典
    json_data = json.loads(json_data)
    print(type(json_data))
    print(json_data)
    for item in json_data['data']:
        print(item['k'],'---',item['v'])

     

    '''
    案例v9
    访问一个网址
    更改自己的UserAgent进行伪装
    '''
    from urllib import request, error
    if __name__ == '__main__':
        url='http://www.baidu.com'
        try:
            # 使用heads方法伪装UA
            # 第一种方法
            #headers = {}
            #headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36'
            #req = request.Request(url, headers=headers)
    
            # 第二种方法
            req = request.Request(url)
            req.add_header('User-Agent','Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36')
    
            rsp = request.urlopen(req)
            html = rsp.read().decode()
            print(html)
        except error.HTTPError as e:
            print(e)
        except error.URLError as e:
            print(e)
        except Exception as e:
            print(e)
        print('Done...')

     

     

    # 案例v13
    from urllib import request,parse
    from http import cookiejar
    
    # 创建一个cookiejar的实例
    cookie = cookiejar.CookieJar()
    # 生成cookie管理器
    cookie_handler = request.HTTPCookieProcessor(cookie)
    # 生成http请求管理器
    http_handler = request.HTTPHandler()
    # 生成https管理器
    https_handler = request.HTTPSHandler()
    # 创建请求管理器
    opener = request.build_opener(http_handler, https_handler, cookie_handler)
    
    def login():
        '''
        负责初次登陆
        需要输入用户名密码,用来获取登陆cookie凭证
        :return:
        '''
        # 点击登陆按钮后,观察Network下发送的请求
        url = 'http://study.miaov.com/account/login/ajaxindex'
        # 此值需要从页面中用户名和密码的元素中提取
        data = {
            "account":"188xxxxxxxx",
            "pwd":"xxxxxxxxxx"
        }
        # 把数据进行编码
        data = parse.urlencode(data).encode()
        # 创建一个请求对象
        req = request.Request(url, data)
        # 使用opener发起请求
        rsp = opener.open(req)
    def getHomePage():
        url = "http://study.miaov.com/account/user/history"
        # 如果已经执行了login函数,则opener自动已经包含对应的cookie
        rsp = opener.open(url)
        html = rsp.read().decode()
        with open("rsp_v13.html", "w") as f:
            f.write(html)
    if __name__ == '__main__':
        login()
        getHomePage()
    # 案例v14
    # 在案例v13基础上打印cookie
    from urllib import request,parse
    from http import cookiejar
    
    # 创建一个cookiejar的实例
    cookie = cookiejar.CookieJar()
    # 生成cookie管理器
    cookie_handler = request.HTTPCookieProcessor(cookie)
    # 生成http请求管理器
    http_handler = request.HTTPHandler()
    # 生成https管理器
    https_handler = request.HTTPSHandler()
    # 创建请求管理器
    opener = request.build_opener(http_handler, https_handler, cookie_handler)
    
    def login():
        '''
        负责初次登陆
        需要输入用户名密码,用来获取登陆cookie凭证
        :return:
        '''
        # 点击登陆按钮后,观察Network下发送的请求
        url = 'http://study.miaov.com/account/login/ajaxindex'
        # 此值需要从页面中用户名和密码的元素中提取
        data = {
            "account":"188xxxxxxxx",
            "pwd":"xxxxxxxxxx"
        }
        # 把数据进行编码
        data = parse.urlencode(data).encode()
        # 创建一个请求对象
        req = request.Request(url, data)
        # 使用opener发起请求
        rsp = opener.open(req)
    
    if __name__ == '__main__':
        '''
        执行完login之后,会得到授权孩子后的cookie
        然后我们尝试把cookie打印出来
        '''
        login()
        print(cookie)
        for item in cookie:
            print(type(item))
            print(item)
           
    # 案例v15
    # 修改案例v13,改用文件管理cookie
    from urllib import request,parse
    from http import cookiejar
    
    filename = "cookie.txt"
    # 创建一个cookiejar的实例
    cookie = cookiejar.MozillaCookieJar(filename)
    # 生成cookie管理器
    cookie_handler = request.HTTPCookieProcessor(cookie)
    # 生成http请求管理器
    http_handler = request.HTTPHandler()
    # 生成https管理器
    https_handler = request.HTTPSHandler()
    # 创建请求管理器
    opener = request.build_opener(http_handler, https_handler, cookie_handler)
    
    def login():
        '''
        负责初次登陆
        需要输入用户名密码,用来获取登陆cookie凭证
        :return:
        '''
        # 点击登陆按钮后,观察Network下发送的请求
        url = 'http://study.miaov.com/account/login/ajaxindex'
        # 此值需要从页面中用户名和密码的元素中提取
        data = {
            "account":"188xxxxxxxx",
            "pwd":"xxxxxxxxxx"
        }
        # 把数据进行编码
        data = parse.urlencode(data).encode()
        # 创建一个请求对象
        req = request.Request(url, data)
        # 使用opener发起请求
        rsp = opener.open(req)
        # 保存cookie到文件
        # ignore_discard表示即使cookie将要被丢弃也要保存
        # ignore_expires表示如果该文件中cookie即便已经过期,也要保存
        cookie.save(ignore_discard=True, ignore_expires=True)
    if __name__ == '__main__':
    login()
    # 案例v16
    # 读取v15生成的cookie
    from urllib import request,parse
    from http import cookiejar
    
    # 创建一个cookiejar的实例
    cookie = cookiejar.MozillaCookieJar()
    cookie.load("cookie.txt", ignore_discard=True, ignore_expires=True)
    # 生成cookie管理器
    cookie_handler = request.HTTPCookieProcessor(cookie)
    # 生成http请求管理器
    http_handler = request.HTTPHandler()
    # 生成https管理器
    https_handler = request.HTTPSHandler()
    # 创建请求管理器
    opener = request.build_opener(http_handler, https_handler, cookie_handler)
    
    
    def getHomePage():
        url = "http://study.miaov.com/account/user/history"
        # 如果已经执行了login函数,则opener自动已经包含对应的cookie
        rsp = opener.open(url)
        html = rsp.read().decode()
        with open("rsp_v16.html", "w") as f:
            f.write(html)
    if __name__ == '__main__':
        getHomePage()
  • 相关阅读:
    【Vim】多文件操作
    TC(Traffic Control)命令—linux自带高级流控
    【ceph | 运维】亲和性
    【Vim】Vim分屏基本操作
    Dubbo常用功能06集群容错
    Dubbo负载均衡策略轮询
    Redis知识体系
    Dubbo常用功能09参数回调
    Dubbo负载均衡策略最少活跃调用数
    Dubbo常用功能10异步调用
  • 原文地址:https://www.cnblogs.com/Cloudloong/p/10002371.html
Copyright © 2011-2022 走看看