• 《数据采集与网络爬虫》之抓取网页


     

    一、urllib库的使用

    1、简单使用urllib库爬取整个网页源代码

    import urllib.request
    url='http://www.baidu.com'
    response=urllib.request.urlopen(url)
    print(type(response)) # <class 'http.client.HTTPResponse'>
    print(dir(response)) # dir用来显示该对象所有的方法和属性
    print(type(response.read())) # <class 'bytes'>
    print(response.read().decode()) # decode()默认使用UTF-8进行解码
    print(response.geturl()) # http://www.baidu.com
    print(response.getcode()) # 200
    print(response.info()) # Bdpagetype: 1...
    print(response.headers) # 和info()一样

     

    2、简单使用urllib发出带参数的GET请求

    import urllib.request
    import urllib.parse
    
    url='http://www.baidu.com/s'
    params={'wd':'NBA全明星'} # 字典格式
    params=urllib.parse.urlencode(params) # 对参数进行url编码
    print(params) # wd=NBA%E5%85%A8%E6%98%8E%E6%98%9F
    url=url+'?'+params # http://www.baidu.com/s?wd=NBA%E5%85%A8%E6%98%8E%E6%98%9F
    response=urllib.request.urlopen(url)
    print(response.read().decode())

    3、使用urllib发出POST请求

    import urllib.request
    import urllib.parse
    url='http://httpbin.org/post'
    data={'username':'恩比德','age':28}
    data=urllib.parse.urlencode(data) 
    print(data) # username=%E6%81%A9%E6%AF%94%E5%BE%B7&age=28   url解码可使用urllib.parse.unquote(str)
    data=bytes(data.encode()) # POST请求发送的数据必须是bytes,一般先要进行url编码,然后转换为bytes
    request=urllib.request.Request(url,data=data) # 只要指定data参数,就一定是POST请求
    response=urllib.request.urlopen(request) # 使用构造的Request对象,通过urlopen方法发送请求
    print(response.read().decode())

    4、使用urllib伪装成浏览器发出请求

    import urllib.request
    url='http://httpbin.org/get'
    # User-Agent用来指定使用的浏览器
    headers={'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36'}
    request=urllib.request.Request(url,headers=headers) # 指定headers参数构造Request对象
    response=urllib.request.urlopen(request) # 使用Request对象发出请求
    print(response.read().decode())

    5、使用代理IP发出请求

    import urllib.request
    import random
    
    # 免费的代理IP列表,zhimahttp.com,免费代理IP寿命短,速度慢,匿名度不高
    proxy_list = [
        {'http': '183.166.180.184:9999'},
        {'http': '221.230.216.169:8888'},
        {'http': '182.240.34.61:9999'},
        {'http': '121.226.154.250:8080'}
    ]
    
    proxy = random.choice(proxy_list) # 随机选择一个
    print(proxy)
    
    # 1.构造ProxyHandler
    proxy_handler = urllib.request.ProxyHandler(proxy)
    
    # 2.使用构造好的ProxyHandler对象来自定义opener对象
    opener = urllib.request.build_opener(proxy_handler)
    
    # 3.使用代理发出请求
    request = urllib.request.Request('http://www.baidu.com') # 构造请求对象传入opener对象的open()方法
    response = opener.open(request)
    
    print(response.read().decode())

    我们可以使用代理服务器,每隔一段时间换一个代理。如果某个IP被禁止,那么就可以换成其他IP继续爬取数据,从而可以有效解决被网站禁止访问的情况。

     

    6、URLError异常和捕获

    import urllib.request
    import urllib.error
    url='http://www.whit.edu.cn/net' # 错误url
    request = urllib.request.Request(url)
    try:
            urllib.request.urlopen(request)
    except urllib.error.HTTPError as e:
            print(e.code) # 404

    7、捕获超时异常

    import urllib.request
    import urllib.error
    try:
           url = 'http://218.56.132.157:8080'
           # timeout设置超时的时间
           response = urllib.request.urlopen(url, timeout=1)
           result = response.read()
           print(result)
    except Exception as error:
           print(error) # <urlopen error timed out>

    二、requests库的使用

    1、使用requests发出带参数的get请求

    import requests
    params={'wd':'爬虫'}
    url='http://www.baidu.com/s'
    response=requests.get(url,params=params)
    print(response.text)
    # print(type(response)) # <class 'requests.models.Response'>
    # print(response.encoding) # utf-8
    # print(type(response.content)) # <class 'bytes'>
    # print(response.content.decode()) # 和response.text的结果一样

    说明:使用requests发出带参数的GET请求时,参数使用字典格式,无需url编码,无需拼接url。和“一”中的“2”对比一下。

    Response对象常用的属性:

      text:响应内容的字符串形式

      encoding:响应内容的编码方式

      status_code:状态码

    2、使用requests库发送POST请求

    import requests
    url="http://httpbin.org/post"
    data={'name':'库里'} # POST请求要发送的数据
    response=requests.post(url,data)
    print(response.text)

    说明:使用requests发出POST请求时,要发送的数据使用字典格式,无需url编码,无需转换为bytes。和“一”中“3”对比一下。

    三、访问带https网站

    import urllib.request
    import requests
    import ssl
    
    url="https://www.runoob.com/"
    headers={'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36'}
    
    # 1.urllib不伪装浏览器,直接访问
    # print("1."+'-'*50)
    # response=urllib.request.urlopen(url)
    # print(response.read().decode())
    # urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:833)>
    
    # 2.urllib伪装成浏览器访问
    # print("2."+'-'*50)
    # request=urllib.request.Request(url,headers=headers)
    # response=urllib.request.urlopen(request)
    # print(response.read().decode())
    # urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:833)>
    
    # 3.urllib不伪装浏览器,导入ssl模块
    # 当使用urllib模块访问https网站时,由于需要提交表单,而python3默认是不提交表单的,所以这时只需在代码中加上以下代码即可。
    # ssl._create_default_https_context = ssl._create_unverified_context
    # print("3."+'-'*50)
    # response=urllib.request.urlopen(url)
    # print(response.read().decode())
    # OK
    
    # 4.request不伪装浏览器访问
    print("4."+'-'*50)
    response=requests.get(url)
    response.encoding="UTF-8"
    html=response.text
    print(html)
    # OK
    
    # 5.request伪装浏览器访问
    # print("5."+'-'*50)
    # response=requests.get(url,headers)
    # response.encoding="UTF-8"
    # html=response.text
    # print(html)
    # OK
    1.对于带https的网站,urllib模块无论是伪装浏览器还是不伪装浏览器,都会出现证书验证证失败的错误,
    但可以尝试导入ssl模块,并设置访问时忽略证书验证。
    2.对于带https的网站,requests一般可直接访问,如果不能访问,则可尝试伪装成浏览器访问。
    3.对于有些反爬措施比较厉害的网站,如果某个IP频繁访问超过规定的次数,IP可能会被禁用,可使用代理IP
    继续访问。
    所以,尽量使用requests库,不行的话,伪装成浏览器再试试,再不行的话,使用代理IP访问。
  • 相关阅读:
    理解Python闭包,这应该是最好的例子
    2021-01-31
    论unity中UI工具与GUI函数
    2021-01-31
    第八届“图灵杯”NEUQ-ACM程序设计竞赛(全题解&&详细)
    第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛(同步赛)全题解
    Go-快速排序
    网络地址转换NAT原理及其作用
    解析私有IP地址和公网IP地址
    first blog
  • 原文地址:https://www.cnblogs.com/beast-king/p/14500618.html
Copyright © 2020-2023  润新知