zoukankan      html  css  js  c++  java
  • Python爬虫基础之Urllib

    一、随时随地爬取一个网页下来

      怎么爬取网页?对网站开发了解的都知道,浏览器访问Url向服务器发送请求,服务器响应浏览器请求并返回一堆HTML信息,其中包括html标签,css样式,js脚本等。Chrome F2可以看到网页源码。

    css用于网页背景,控件位置,文本粗细等样式布局,js(javascript)相对于静态的css是一种动态的概念,可以跟用户交互,例如单击后弹窗,文本提示,日期控件等,html主要用于信息的展示,文字

    图片,链接等,这是我们要爬取的内容。现在我们使用Python的Urllib库写个脚本开始爬取网页。

    二、Python Urllib库的基本使用

    1)urllib.request.urlopen()方法

    1 import urllib.request
    2 
    3 
    4 response = urllib.request.urlopen('http://www.baidu.com/')
    5 print(response.read())
    response = urllib.request.urlopen('http://www.baidu.com/')
    urlopen方法传递了一串字符串"http://www.baidu.com/",这个参数代表请求的目标链接地址,结果返回一个urllib.response对象。
    
    
    
    

    2)Urllib.request.Request()对象

    1 import urllib.request
    2 
    3 
    4 request = urllib.request.Request('http://www.baidu.com/')
    5 
    6 response = urllib.request.urlopen(request)
    7 
    8 print(response.read())
    request = urllib.request.Request('http://www.baidu.com/')
    response = urllib.request.urlopen(request)

       urlopen()方法不仅支持传递url字符串,还支持一个urllib.request.Request对象。对于Python urllib.request模块的urlopen()方法,官方有这样一句话Open the URL url, which can be either a string or a Request object.
       意思是说urlopen可以接受字符串格式的url或者一个Request对象(具体请移步官方文档,urllib.request
       这里声明了一个Request对象,并作为参数传递给urlopen方法。

    
    

    3)GET和POST请求方式

     POST请求方式

     1 import urllib.request
     2 import urllib.response
     3 import urllib.parse
     4 
     5 params = {"t": "b", "w": "Python urllib"}
     6 params = urllib.parse.urlencode(params)  # urlencode会将dict格式参数拼接并编码 w=Python+urllib&t=b
     7 data = params.encode('ascii')  # 字符串转换为字节(bytes)b'w=Python+urllib&t=b
     8 request = urllib.request.Request('http://zzk.cnblogs.com/s', data=data)
     9 response = urllib.request.urlopen(request)
    10 print(response.read())

    GET请求方式

     1 import urllib.request
     2 import urllib.response
     3 import urllib.parse
     4 
     5 
     6 params = {"t": "b", "w": "Python urllib"}
     7 params = urllib.parse.urlencode(params)  # urlencode会将dict格式参数拼接并编码 w=Python+urllib&t=b
     8 url = "http://zzk.cnblogs.com/s?%s" % params  # 参数urlencode编码并拼接到请求url后面
     9 request = urllib.request.Request(url)
    10 response = urllib.request.urlopen(request)
    11 print(response.read())

    4)响应内容编码

    import urllib.request
    
    response = urllib.request.urlopen('http://www.baidu.com/')
    print(response.read().decode('utf-8'))

    response.read()返回byte字节格式数据,无法直接读懂,需要进行编码,通常使用UTF-8进行编码。通过字符串的decode('utf-8')方法进行解码,上面的代码调整为response.read().decode('utf-8'),这样我们就能像在浏览器上

    一样看懂返回的信息。

    三、Python Urllib库的高级使用

    1)请求头Headers

     1 import urllib.request
     2 import urllib.response
     3 import urllib.parse
     4 
     5 
     6 params = {"t": "b", "w": "Python urllib"}
     7 params = urllib.parse.urlencode(params)  # urlencode会将dict格式参数拼接并编码 w=Python+urllib&t=b
     8 data = params.encode('ascii')  # 字符串转换为字节(bytes)b'w=Python+urllib&t=b
     9 headers = {
    10     "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"}
    11 request = urllib.request.Request('http://zzk.cnblogs.com/s', data=data, headers=headers)
    12 response = urllib.request.urlopen(request)
    13 print(response.read().decode('utf-8'))
    request = urllib.request.Request('http://zzk.cnblogs.com/s', data=data, headers=headers)

        Headers是字典类型,比较常见的请求头是User-Agent,可以认为是浏览器的一个身份认证,一些HTTP服务器只会接受来自浏览器的请求,例如“Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110                 Safari/537.36,如果不为指定User-Agent,请求会默认带上Python Urllib的User Agent  “Python-urllib/2.6” ,有可能请求会被服务器拒绝。

        可以通过传递字典类型的请求头Headers,还可以通过request对象的方法add_header(key,val)设置请求头,

    request.add_header('User-Agent','Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36')

        还有Request.full_url、Request.get_full_url()、Request.get_header()、Request.has_header()等实用的属性和方法 (详细请查看官方Request Object)

    2)代理设置Proxy和HTTP Authentication

     1 import urllib.request
     2 import urllib.response
     3 import urllib.parse
     4 
     5 proxy_handler = urllib.request.ProxyHandler({'http': 'http://www.example.com:3128/'})
     6 proxy_auth_handler = urllib.request.ProxyBasicAuthHandler()
     7 proxy_auth_handler.add_password(realm='realm', uri='http://wwww.example.com:3128/', user='username', passwd='password')
     8 
     9 opener = urllib.request.build_opener(proxy_handler, proxy_auth_handler)
    10 urllib.request.build_opener(opener)
    11 response = urllib.request.urlopen('http://www.baidu.com')  # 向代理服务器www.example.com:3128发送请求,代理服务器接收请求并转发请求给www.baidu.com服务器
    12 print(response.read().decode('utf-8'))

     HTTP代理本质上是一个Web应用,它和其他普通Web应用没有根本区别。HTTP代理收到请求后,根据Header中Host字段的主机名和Get/POST请求地址综合判断目标主机,建立新的HTTP请求并转发请求数据,并将收到的响应数据转发给客户端。如果请求地址

    是绝对地址,HTTP代理采用该地址中的Host,否则使用Header中的HOST字段。

    3)超时设置Timeout

    方法一、设置单个请求超时时间:

    1 import urllib.request
    2 
    3 timeout = 2  # set timeout 2 seconds
    4 response = urllib.request.urlopen('http://www.baidu.com/', timeout=timeout)
    5 print(response.read().decode('utf-8'))

    方法二、设置全局请求超时时间:

     1 import urllib.request
     2 import urllib.parse
     3 import urllib.error
     4 import socket
     5 
     6 socket.setdefaulttimeout(60)    # 设置全局超时时间
     7 
     8 params = {"t": "b", "w": "Python urllib"}
     9 params = urllib.parse.urlencode(params)  # urlencode会将dict格式参数拼接并编码 w=Python+urllib&t=b
    10 url = "http://zzk.cnblogs.com/s?%s" % params  # 参数urlencode编码并拼接到请求url后面
    11 request = urllib.request.Request(url)
    12 response = urllib.request.urlopen(request)
    13 print(response.read().decode('utf-8'))

    四、Python Urllib库的实际应用

    1)请求失败重试

     1 # 请求失败,默认重试2次
     2 def download(url, user_agent='wswp', num_retries=2):
     3     if url is None:
     4         return None
     5     print('Downloading:', url)
     6     headers = {
     7         'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'}
     8     request = urllib.request.Request(url, headers=headers) 
     9     try:
    10         html = urllib.request.urlopen(request).read().decode('utf-8')
    11     except urllib.error.URLError as e:
    12         print('Downloading Error:', e.reason)
    13         html = None
    14         if num_retries > 0:
    15             if hasattr(e, 'code') and 500 <= e.code < 600:
    16                 # retry when return code is 5xx HTTP erros
    17                 return download(url, num_retries - 1)
    18     return html

    我们一无所成的主要原因是想的太多,而做的太少!

  • 相关阅读:
    linux基础学习2
    linux下部署项目问题
    ThinkPHP上传返回 “文件上传保存错误!”
    jQuery自定义插件
    对于nginx为什么能提高性能
    WebSocket 是什么原理?为什么可以实现持久连接?
    数据库的左右外连接
    漫画说算法--动态规划算法一(绝对通俗易懂,非常棒)
    Integer.MIN_VALUE
    反射
  • 原文地址:https://www.cnblogs.com/taotaoblogs/p/7142589.html
Copyright © 2011-2022 走看看