美文网首页Python
[CP_07] Python爬虫之urllib库数据挖掘、实践案

[CP_07] Python爬虫之urllib库数据挖掘、实践案

作者: Fighting_001 | 来源:发表于2019-03-27 00:48 被阅读0次

    目录结构

    一、urllib库的应用
        1. Python爬虫入门案例
        2. 自定义请求
        3. 伪装浏览器原理
            1)单个User-Agent爬虫-案例
            2)多个User-Agent爬虫-案例
        4. 自定义opener
        5. 使用代理IP
    二、Python爬虫-实践案例
        1. 处理GET请求
        2. 网页翻页下载爬虫-案例
        3. 处理POST请求案例:实现词语中英文翻译
    三、异常处理 & cookie模拟登录
        1. 异常处理
        2. cookie模拟登录
    

    一、urllib库的应用

    1. Python爬虫入门案例

    案例:利用Python请求获取指定url的响应数据(获取信息),然后对获取的数据进行正则匹配以提取指定的内容(清洗信息)
    crawler001.py

    from urllib import request
    import re
    
    # 获取信息
    # 确定爬虫的对象url
    url=r"http://www.sogou.com"
    # 发送请求,获取响应信息
    data=request.urlopen(url).read()
    data=data.decode()  # 解码:bytes转字符串,展示中文
    
    # 清洗信息
    # 定义正则,匹配title标签中任意长度的任意字符
    pat="<title>(.*?)</title>"
    data=re.findall(pat,data)   # 在响应数据中匹配符合正则的字符串
    
    print(data)
    

    清洗数据之前,所获取的响应数据为:

    清洗数据之后,提取的信息为:

    2. 自定义请求

    crawler002.py

    from urllib import request
    import re
    
    # 获取信息
    url=r"http://www.sogou.com"
    # 创建自定义请求对象(可封装url、User-Agent...)
    rq=request.Request(url)
    # 发送请求,获取响应信息
    data=request.urlopen(rq).read()
    data=data.decode()
    
    # 清洗信息
    pat="<title>(.*?)</title>"
    data=re.findall(pat,data)
    
    print(data[0])
    

    备注说明:
    crawler001.py 是直接在urlopen()中放入url,此时只封装了url
    crawler002.py 通过自己创建自定义对象(rq),可封装url、User-Agent等信息(应对反爬虫机制),不限于只能封装url

    3. 伪装浏览器原理

    反爬虫机制:
    ① 通过判断是否使用浏览器访问,若是则通过访问,若不是则拦截访问
    ② 通过使用与真实浏览器一致的User-Agent信息,伪装为浏览器进行访问;同一个浏览器,不同请求对应的User-Agent信息是一致的
    ③ 多线程实现多次循环爬取时,若只采用同一个User-Agent,很可能被拦截访问,此时每次循环时需要从众多不同的User-Agent中随机获取使用

    传送门:
    常用浏览器(PC,移动) user-agent
    手机UserAgent库

    1)单个User-Agent爬虫-案例

    crawler003.py

    from urllib import request
    import re
    
    # 获取信息
    url=r"http://www.sogou.com"
    # 创建header字典(构造浏览器中的Request Headers)
    header={
    "User-Agent":"Mozilla/5.0 (Windows NT 6.1; rv:65.0) Gecko/20100101 Firefox/65.0"
    }
    # 创建自定义请求对象(可封装url、User-Agent...)
    rq=request.Request(url,headers=header)
    # 发送请求,获取响应信息
    data=request.urlopen(rq).read()
    data=data.decode()
    
    # 清洗信息
    pat="<title>(.*?)</title>"
    data=re.findall(pat,data)
    
    print(data[0])
    
    2)多个User-Agent爬虫-案例

    crawler004.py

    from urllib import request
    import re
    import random
    
    # 获取信息
    url=r"http://www.sogou.com"
    
    agent1="User-Agent,Mozilla/5.0 (Windows NT 6.1; rv:65.0) Gecko/20100101 Firefox/65.0"
    agent2="User-Agent, Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11"
    agent3="User-Agent,Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11"
    agent4="User-Agent, MQQBrowser/26 Mozilla/5.0 (Linux; U; Android 2.3.7; zh-cn; MB200 Build/GRJ22; CyanogenMod-7) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"
    agent5="Mozilla/5.0 (Linux; U; Android 8.1.0; zh-cn; BLA-AL00 Build/HUAWEIBLA-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/8.9 Mobile Safari/537.36"
    agent6="Mozilla/5.0 (Linux; Android 5.1.1; vivo X6S A Build/LMY47V; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/044207 Mobile Safari/537.36 MicroMessenger/6.7.3.1340(0x26070332) NetType/4G Language/zh_CN Process/tools"
    ls=[agent1,agent2,agent3,agent4,agent5,agent6]
    agent=random.choice(ls)
    print(agent)
    
    # 创建header字典(构造浏览器中的Request Headers)
    header={"User-Agent":agent}
    # 创建自定义请求对象(可封装url、User-Agent...)
    rq=request.Request(url,headers=header)
    # 发送请求,获取响应信息
    data=request.urlopen(rq).read()
    data=data.decode()
    
    # 清洗信息
    pat="<title>(.*?)</title>"
    data=re.findall(pat,data)
    
    print(data[0])
    

    4. 自定义opener

    其前使用的urlopen是一个特殊的opener(模块构建好的对象),但urlopen()方法不支持代理、cookie等高级功能。为支持此类功能,通过request.build_opener()方法创建自定义opener对象;使用自定义的opener对象,调用open()方法发送请求。
    若程序里所有请求都使用自定义的opener,则可使用request.install_opener()将自定义的opener 对象定义为全局opener,当调用urlopen,都将使用这个opener。

    opener.py

    from urllib import request
    
    # 构建HTTP处理器对象(专门处理请求的对象)
    http_hander=request.HTTPHandler()
    # 创建自定义的opener对象
    opener=request.build_opener(http_hander)
    
    # 创建自定义请求对象
    url="http://www.sogou.com"
    rq=request.Request(url)
    
    # 发送请求,获取响应
    rp=opener.open(rq).read().decode()
    
    print(rp)
    

    将opener对象设置为全局对象,当使用urlopen时也会调用opener对象,如下:
    global-opener.py

    from urllib import request
    
    # 构建HTTP处理器对象(专门处理请求的对象)
    http_hander=request.HTTPHandler()
    # 创建自定义的opener对象
    opener=request.build_opener(http_hander)
    
    # 创建自定义请求对象
    url="http://www.sogou.com"
    rq=request.Request(url)
    
    # 发送请求,获取响应
    # rp=opener.open(rq).read().decode()
    
    # 将自定义opener设置为全局对象
    request.install_opener(opener)
    # 此时使用urlopen也会调用opener对象
    rp=request.urlopen(rq).read().decode()
    
    print(rp)
    

    5. 使用代理IP

    反爬虫方式1:使用User-Agent,伪装成浏览器发送请求
    反爬虫方式2:判断请求来源的IP地址,使用代理IP

    传送门:西刺免费代理IP

    proxy.py

    from urllib import request
    import random
    
    # 代理IP组成的列表
    proxylist=[
        {"http":"221.10.159.234:1337"},
        {"http":"61.189.242.243:55484"},
        {"http":"112.85.169.8:9999"},
        {"http":"114.119.116.92:61066"},
        {"http":"110.52.235.65:9999"},
        {"http":"27.43.189.219:9999"}
    ]
    # 从以上IP列表中随机取出1个IP
    proxy=random.choice(proxylist)
    print(proxy)
    
    # 构建代理处理器对象
    proxyHandler=request.ProxyHandler(proxy)
    # 创建自定义opener对象
    opener=request.build_opener(proxyHandler)
    # 创建请求对象
    url="http://www.sogou.com"
    rq=request.Request(url)
    # 发送请求,获取响应
    rp=opener.open(rq).read().decode()
    print(rp)
    

    二、Python爬虫-实践案例

    1. 处理GET请求

    get.py

    import urllib
    from urllib import request
    
    # http://www.sogou.com/web?query=%E6%B5%8B%E8%AF%95
    
    # 分离url中的中文参数项
    query={"query":"测试"}
    url_0="http://www.sogou.com/web?"
    
    # 构造url的参数值编码;parse解析url
    q=urllib.parse.urlencode(query)
    print(q)
    url=url_0+q # 拼接为完整的url请求链接
    
    # 创建请求对象
    rq=request.Request(url)
    # 发送请求,获取响应
    rp=request.urlopen(rq).read().decode()
    print(rp)
    

    2. 网页翻页下载爬虫-案例

    案例目标:根据用户输入的关键词,进入对应公众号搜索结果页面,从指定页码范围下载html文件存储到本地

    分析页码的规律:
    第1页 ==> http://weixin.sogou.com/weixin?query=python&_sug_type_=&s_from=input&_sug_=y&type=1&page=1&ie=utf8
    第2页 ==> http://weixin.sogou.com/weixin?query=python&_sug_type_=&s_from=input&_sug_=y&type=1&page=2&ie=utf8
    第3页 ==> http://weixin.sogou.com/weixin?query=python&_sug_type_=&s_from=input&_sug_=y&type=1&page=3&ie=utf8
    第4页 ==> http://weixin.sogou.com/weixin?query=python&_sug_type_=&s_from=input&_sug_=y&type=1&page=4&ie=utf8

    页码规律:page=页码

    web-page-store.py

    from urllib import request
    import urllib
    
    header={
    "User-Agent":"Mozilla/5.0 (Windows NT 6.1; rv:65.0) Gecko/20100101 Firefox/65.0"
    }
    
    # 方法1:发送url请求,从服务器获取响应文件(爬取网页)
    def loadPage(fullurl,filename):
        print("正在下载:",filename)
        rq=request.Request(fullurl,headers=header)
        rp=request.urlopen(rq).read()
        return rp
    
    # 方法2:将HTML内容写入本地保存
    def writePage(html,filename):
        print("正在保存:",filename)
        with open(filename,"wb") as f:
            f.write(html)
        print("-----------")
    
    # 方法3:处理指定页码范围的页面的url(调用<方法1+方法2>)
    def storeData(url,start,end):
        for i in range(start,end+1):
            page=i
            fullurl=url+"&page="+str(page)  # 每次请求的完整url
            # 每次请求后保存的文件名
            filename=r"D:\CI_Env\Python_Test\file\第"+str(page)+"页.html"
            html=loadPage(fullurl,filename) # 调用爬虫,爬取网页
            writePage(html,filename)    # 将获取到的html网页内容写入本地保存
    
    # 主函数:通过程序入口控制代码执行(调用方法3)
    if __name__ == '__main__':
        query=input("请输入公众号关键词:")
        start=int(input("请输入起始页码:"))
        end=int(input("请输入终止页码:"))
    
        url="http://weixin.sogou.com/weixin?"
        para=urllib.parse.urlencode({"query":query})    # 解析参数取值
        url=url+para
    
        storeData(url,start,end)    # 调用执行处理指定页码的url
    

    执行结果:

    3. 处理POST请求案例:实现词语中英文翻译

    案例目标:根据用户输入的词语(中文or英文),实现中英文互译

    原始url:http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule
    调整url:http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule
    请求方式:POST

    代码实现:
    yd-fanyi.py

    from urllib import request
    import urllib
    import re
    
    header={
    "User-Agent":"Mozilla/5.0 (Windows NT 6.1; rv:65.0) Gecko/20100101 Firefox/65.0"
    }
    
    url="http://fanyi.youdao.com/translate?smartresult:dict&smartresult:rule"
    
    words=input("翻译词语:")
    
    # POST请求需要提交的参数(表单数据为字典类型)
    formdata={
        "i":words,
        "from":"AUTO",
        "to":"AUTO",
        "smartresult":"dict",
        "client":"fanyideskweb",
        "salt":"15535312968212",
        "sign":"d6bd41d13ab6467bec455ff06c356b33",
        "ts":"1553531296821",
        "bv":"e2a78ed30c66e16a857c5b6486a1d326",
        "doctype":"json",
        "version":"2.1",
        "keyfrom":"fanyi.web",
        "action":"FY_BY_REALTlME",
        "typoResult":"false"
    }
    
    # 经过urlencode转码,然后用utf-8进行编码
    data=urllib.parse.urlencode(formdata).encode(encoding='utf-8')
    # 创建POST请求对象
    req=request.Request(url,data=data,headers=header)
    # 发送请求,获取响应数据
    resp=request.urlopen(req).read().decode()
    
    # 定义正则,提取翻译的内容(此时为list类型)
    pat=r'"tgt":"(.*?)"'
    result=re.findall(pat,resp)
    # 从列表中获取翻译的有效内容
    print("翻译结果:",result[0])
    

    执行结果:

    三、异常处理 & cookie模拟登录

    1. 异常处理

    爬虫过程中请求次数较多的场景,有可能某些请求可正常执行,某些请求异常。当请求出现异常时,为了不影响后续请求能够继续执行,需要引入异常处理机制(如:Try/Except)

    exception1.py

    from urllib import request
    
    list1=[
    "http://www.baidu.com",
    "http://www.sogou.com",
    "http://abc.123.xyz",
    "http://cn.bing.com",
    "http://www.yahoo.com"
    ]
    
    i=0
    for url in list1:
        i=i+1
        request.urlopen(url)
        print("完成请求",i)
    

    未对异常处理时,执行结果:

    exception2.py

    from urllib import request
    
    list1=[
    "http://www.baidu.com",
    "http://www.sogou.com",
    "http://abc.123.xyz",
    "http://cn.bing.com",
    "http://www.yahoo.com"
    ]
    
    i=0
    for url in list1:
        i=i+1
        try:
            request.urlopen(url)
            print("完成请求",i)
        except Exception as e:
            print(e)
    

    处理过异常,执行结果:

    2. cookie模拟登录

    cookie常用作保持登录状态。若登录成功,则会出现提示登录的用户名:

    cookie.py

    from urllib import request
    import re
    
    url="http://localhost/dvwa/index.php"
    
    header={
        "User-Agent":"Mozilla/5.0 (Windows NT 6.1; rv:65.0) Gecko/20100101 Firefox/65.0",
        "Cookie":"security=impossible; PHPSESSID=pdujt5fsk535jscvotfma0bq26"
    }
    
    # 创建请求对象(GET请求)
    req=request.Request(url,headers=header)
    # 发送请求,获取响应数据
    resp=request.urlopen(req).read().decode()
    # print(resp)
    
    # 定义正则,提取登录后才能获取的有效信息
    pat1=r"<h1>(.*?)</h1>"
    pat2=r"<em>Username:</em> (.*?)<br />"
    result1=re.findall(pat1,resp)
    result2=re.findall(pat2,resp)
    print(result1[0]+"\n"+result2[0])
    

    执行结果:

    相关文章

      网友评论

        本文标题:[CP_07] Python爬虫之urllib库数据挖掘、实践案

        本文链接:https://www.haomeiwen.com/subject/qwlyvqtx.html