Urllib是Python提供的一个用于操作URL的模块,常用于网页的爬取。这里的环境为python3,如果是python2用法稍有不同。

快速开始爬取网页

下面是一个urllib爬取网页并保存的简单例子

import urllib.request
url= "http://www.baidu.com"
data=urllib.request.urlopen(url).read()
fhandle=open("./1.html","wb")
fhandle.write(data)
fhandle.close()

有些网站设置了反爬虫,没有headers不让访问,下面改进一下,加入headers

import urllib.request
url= "http://www.baidu.com"
headers=("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 SE 2.X MetaSr 1.0")
opener = urllib.request.build_opener()
opener.addheaders = [headers]
data=opener.open(url).read()
fhandle=open("./1.html","wb")
fhandle.write(data)
fhandle.close()

读取内容常见的有3种方式,其用法是:

  1. read()读取文件的全部内容,与readlines()不同的是,read()会把读取到的内容赋给一个字符串变量。
  2. readlines()读取文件的全部内容,readlines()会把读取到的内容赋值给一个列表变量。
  3. readline()读取文件的一行内容。

超时设置

try:
    url= "http://www.baidu.com"
    data=urllib.request.urlopen(url, timeout=10).read()
    print(len(data))
except Exception as e:
    print("出现异常" + str(e))

HTTP协议请求

get请求

利用百度搜索关键字并保存结果网页

import urllib.request
keywd="python"
url="http://www.baidu.com/s?wd="+keywd
req=urllib.request.Request(url)
data=urllib.request.urlopen(req).read()
fhandle=open("./1.html","wb")
fhandle.write(data)
fhandle.close()

如果关键字为中文,需要用quote进行编码。

import urllib.request
url="http://www.baidu.com/s?wd="
key="薄荷盐"
key_code=urllib.request.quote(key)
url_all=url+key_code
req=urllib.request.Request(url_all)
data=urllib.request.urlopen(req).read()
fh=open("./1.html","wb")
fh.write(data)
fh.close()

post请求

这里以登录zabbix网页为例,post账号密码,实现保存登录后的网页。

import urllib.request
import urllib.parse
url = "http://zabbix.work/index.php"
postdata =urllib.parse.urlencode({
    "name": 'Admin',
    "password": 'zabbix',
    "autologin": 1,
    "enter": "登录"
    }).encode('utf-8') #将数据使用urlencode编码处理后,使用encode()设置为utf-8编码
req = urllib.request.Request(url,postdata)
req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 SE 2.X MetaSr 1.0')
data=urllib.request.urlopen(req).read()
fhandle=open("./1.html","wb")
fhandle.write(data)
fhandle.close()

异常处理

爬取网页过程中难免会出现各种异常,主要分为两种一种URL不存在,一种网页打不开,下面是两种处理方式。

import urllib.request
import urllib.error
try:
    urllib.request.urlopen("http://www.boheyan.cn/")
except urllib.error.HTTPError as e:
    print(e.code)
    print(e.reason)
except urllib.error.URLError as e:
    print(e.reason)

上面的代码可简写为:

import urllib.request
import urllib.error
try:
    urllib.request.urlopen("http://www.boheyan.cn/")
except urllib.error.URLError as e:
    if hasattr(e,"code"):
        print(e.code)
    if hasattr(e,"reason"):
        print(e.reason)

使用代理

首先从互联网中搜索对应的代理服务器地址,推荐一个网站:http://www.xicidaili.com/,有大量可用的免费代理IP。

def use_proxy(proxy_addr, url):
    import urllib.request
    proxy = urllib.request.ProxyHandler({'http': proxy_addr})
    opener = urllib.request.build_opener(proxy, urllib.request.HTTPHandler)
    urllib.request.install_opener(opener)
    data = urllib.request.urlopen(url).read().decode('utf-8')
    return data
proxy_addr = '14.118.253.139:6666'
data = use_proxy(proxy_addr, 'http://www.baidu.com')
print(len(data))

不同代理的区别:

    1、透明代理(Transparent Proxy)
    
    REMOTE_ADDR = Proxy IP
    HTTP_VIA = Proxy IP
    HTTP_X_FORWARDED_FOR = Your IP
    透明代理虽然可以直接“隐藏”你的IP地址,但是还是可以从HTTP_X_FORWARDED_FOR来查到你是谁。
    
    2、匿名代理(Anonymous Proxy)
    
    REMOTE_ADDR = proxy IP
    HTTP_VIA = proxy IP
    HTTP_X_FORWARDED_FOR = proxy IP
    匿名代理比透明代理进步了一点:别人只能知道你用了代理,无法知道你是谁。
    
    还有一种比纯匿名代理更先进一点的:混淆代理,见下节。
    
    3、混淆代理(Distorting Proxies)
    
    REMOTE_ADDR = Proxy IP
    HTTP_VIA = Proxy IP
    HTTP_X_FORWARDED_FOR = Random IP address
    
    如上,与匿名代理相同,如果使用了混淆代理,别人还是能知道你在用代理,但是会得到一个假的IP地址,伪装的更逼真:-)
    
    4、高匿代理(Elite proxy或High Anonymity Proxy)
    
    REMOTE_ADDR = Proxy IP
    HTTP_VIA = not determined
    HTTP_X_FORWARDED_FOR = not determined
可以看出来,高匿代理让别人根本无法发现你是在用代理,所以是最好的选择。