Python 爬虫入门(一)urllib的基本使用

参考资料
1.用python开发爬虫 https://www.gitbook.com/book/germey/python3webspider/details
2.论一只爬虫的自我修养 http://blog.fishc.com/category/python/spider
3.Python爬虫学习系列教程 http://cuiqingcai.com/1052.html
4.Beautiful Soup 4.2.0 中文文档 https://wizardforcel.gitbooks.io/bs4-doc/content/
5.Requests: 让 HTTP 服务人类 http://docs.python-requests.org/zh_CN/latest/

前言:
urllib包含四个模块:

  • urllib.request可以用来发送request和获取request的结果
  • urllib.error包含了urllib.request产生的异常
  • urllib.parse用来解析和处理URL
  • urllib.robotparse用来解析页面的robots.txt文件
1. urllib.request的基本使用方法属性
1.1. 使用urllib.request.urlopen()来爬取网页
In [1]: import urllib.request
In [2]: r=urllib.request.urlopen('http://blog.fishc.com/3597.html')
In [3]: r.read().decode('utf-8')
Out[3]: '<!DOCTYPE html>\n<html xmlns="http://www.w3.org/1999/xhtml"><head profile="http://gmpg.org/xfn/11">\n<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />\n<title>论一只爬虫的自我修养2:实战 – 零基础入门学习Python054 | 鱼C工作室</title>\n<meta name="description" content="论一只爬虫的自我修养2:实战" />\n<meta name="keywords" content="Python3下载网页,Python3爬虫,Python3蜘蛛,urllib" />\n<link rel="stylesheet" type="......
In [4]: type(r)
Out[4]: http.client.HTTPResponse

可以看到,使用urllib.request.urlopen()返回的对象是一个http.client.HTTPResponse类型的对象,它主要包含的方法有read(),readinto(),getheader(name),getheaders(),fileno()等函数和msg,versionstatus,reason,debuglevel,closed等属性。

In [8]: r.getheaders()
Out[8]: 
[('Date', 'Sun, 19 Feb 2017 13:08:21 GMT'),
 ('Content-Type', 'text/html; charset=UTF-8'),
 ('Transfer-Encoding', 'chunked'),
 ('Connection', 'close'),
 ('Set-Cookie', 'acw_tc=AQAAANMMjDotOggAUUhyyn/OUgglngLJ; Path=/; HttpOnly'),
 ('Server', 'Fishc'),
 ('Vary', 'Accept-Encoding'),
 ('X-Powered-By', 'PHP/5.6.15'),
 ('X-Pingback', 'http://blog.fishc.com/xmlrpc.php'),
 ('Link', '<http://blog.fishc.com/?p=3597>; rel=shortlink')]
In [9]: r.getheader('server')
Out[9]: 'Fishc'
In [10]: r.status
Out[10]: 200

urllib.request.urlopen()使用具体参数如下:

urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)

(1)使用data参数可发起数据提交请求,相当于post,详细见文章最后实战代码。
(2)使用timeout参数可以限定超时时间,超过则报错,默认不设置,表示始终请求直至手动关闭程序。
(3)context参数,它必须是ssl.SSLContext类型,用来指定SSL设置。cafile和capath两个参数是指定CA证书和它的路径,这个在请求HTTPS链接时会有用。cadefault参数现在已经弃用了,默认为False。

1.2 修改head或者使用代理来防止爬虫被服务器阻拦

使用爬虫对网页发起请求时,若访问量过大则常常会被服务器阻拦,此时可通过修改headers或者使用代理进行访问。
1.修改headers方法有两种:(1)通过Request的headers参数来进行修改 (2)通过Request.add_header()方法来进行添加headers。

# (1)通过Request的headers参数来进行修改
head={}
head['User-Agent']='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
request=urllib.request.Request(url, data, head)     # 创建一个Request对象
response=urllib.request.urlopen(request)  # 爬取网页

# (2)通过`Request.add_header()`方法来进行添加head
request=urllib.request.Request(url, data)     # 创建一个Request对象
 # 添加head
request.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36')  
response=urllib.request.urlopen(request)  # 爬取网页

2.使用代理来进行爬虫可简单分为3步:

# (1)参数是一个字典{'类型':'代理ip:端口号'}
proxy_support=urllib.request.ProxyHandler({})

# (2)定制、创建一个opener(代理)
opener=urllib.request.build_opener(proxy_support)
# opener也可以添加head信息
opener.addheaders=[('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36')]

# (3a)安装opener,安装后以后访问都会使用此代理
urllib.request.install_opener(opener)

# (3b)不安装,调用opener(也即代理)来打开网页
opener.open(url)

# opener也可以添加head信息

2. 使用urllib.error处理异常

主要异常详见使用urllib.error处理异常.
这里主要了解下try,except用法:

import urllib.request
import urllib.error
try:    
   response=urllib.request.urlopen('http://suibiankankan.com')
except urllib.error.URLError as e:
   print(e.reason)

# [Errno -2] Name or service not known   
3. 使用urllib.parse解析链接

使用urllib.parse.urlparse()进行链接解析,拆解链接的各部分内容。

In [17]: import urllib.parse
In [19]: result = urllib.parse.urlparse('http://www.baidu.com/index.html;user?id=5#comment')
In [20]: type(result)
Out[20]: urllib.parse.ParseResult
In [21]: result
Out[21]: ParseResult(scheme='http', netloc='www.baidu.com', path='/index.html', params='user', query='id=5', fragment='comment')
In [22]: result[1]
Out[22]: 'www.baidu.com'
In [24]: result.netloc
Out[24]: 'www.baidu.com'

观察可以看到,返回结果是一个ParseResult类型的对象,它包含了六个部分,分别是schemenetlocpathparamsqueryfragment。使用索引或者属性可以查看解析结果。
由上可以得出一个标准的链接格式如下:

scheme://netloc/path;parameters?query#fragment

使用urllib.parse.urlunparse()可以将几个部分连接起来。

In [25]: data = ['http', 'www.baidu.com', 'index.html', 'user', 'a=6', 'comment']
In [26]: urllib.parse.urlunparse(data)
Out[26]: 'http://www.baidu.com/index.html;user?a=6#comment'

其他的一些方法:
(1)urllib.parse.urlsplit(),这个和urlparse()方法非常相似,只不过它不会单独解析parameters这一部分,只返回五个结果。上面例子中的parameters会合并到path中。
(2)urllib.parse.urlunsplit(),与urlunparse()类似,也是将链接的各个部分组合成完整链接的方法,传入的也是一个可迭代对象。 例如list、tuple等等,唯一的区别是,长度必须为5。
(3)urllib.parse.urljoin(),利用urljoin()方法我们可以提供一个base_url(基础链接),新的链接作为第二个参数,方法会分析base_url的scheme、netloc、path这三个内容对新链接缺失的部分进行补充,作为结果返回。如果这三项在新的链接里面不存在,那么就予以补充,如果新的链接存在,那么就使用新的链接的部分。base_url中的parameters、query、fragments是不起作用的。

In [27]: urllib.parse.urljoin('http://www.baidu.com', 'FAQ.html')
Out[27]: 'http://www.baidu.com/FAQ.html'
4. 使用urllib.robotparser分析robots协议

robots协议也被称作爬虫协议、机器人协议,它的全名叫做网络爬虫排除标准(Robots Exclusion Protocol),同来告诉爬虫和搜索引擎哪些页面可以抓取,哪些不可以抓取。它通常是一个叫做robots.txt的文本文件,放在网站的根目录下。
当一个搜索蜘蛛访问一个站点时,它首先会检查下这个站点根目录下是否存在robots.txt文件,如果存在,搜索蜘蛛会根据其中定义的爬取范围来爬取。如果没有找到这个文件,那么搜索蜘蛛便会访问所有可直接访问的页面。

User-agent: *
Disallow: /
Allow: /public/

以上的两行实现了对所有搜索蜘蛛只允许爬取public目录的作用。
如上简单的两行,保存成robots.txt文件,放在网站的根目录下,和网站的入口文件放在一起。比如index.php、index.html、index.jsp等等。
那么上面的User-agent就描述了搜索蜘蛛的名称,在这里将值设置为*,则代表该协议对任何的爬取蜘蛛有效。比如你可以设置User-agent: Baiduspider,就代表我们设置的规则对百度搜索引擎是有效的。如果有多条User-agent记录,则就会有多个爬取蜘蛛会受到爬取限制,但你至少需要指定一条。
Disallow指定了不允许抓取的目录,比如上述例子中设置为/则代表不允许抓取所有页面。
Allow它一般和Disallow一起使用,一般不会单独使用,现在我们设置为/public/,起到的作用是所有页面不允许抓取,但是public目录是可以抓取的。

urllib.robotparser提供了一个类,叫做RobotFileParser。它可以根据某网站的robots.txt文件来判断一个爬取蜘蛛是否有权限来爬取这个网页。
使用方法:

urllib.robotparser.RobotFileParser(url='')

例子:

rom urllib.robotparser import RobotFileParser

rp = RobotFileParser('http://www.jianshu.com/robots.txt')
rp.read()
print(rp.can_fetch('*', 'http://www.jianshu.com/p/b67554025d7d'))
print(rp.can_fetch('*', "http://www.jianshu.com/search?q=python&page=1&type=collections"))

# True
# False

以上简单介绍urllib的简单用法,下面给出一个实战例子,交互式有道翻译请求:

import urllib.request
import urllib.parse
import json

url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=https://www.google.com.hk/'
data=dict()
data['type']='AUTO'
data['i']=input("Plz input what you want to translate: ")
data['doctype']='json'
data['xmlVersion']='1.8'
data['keyfrom']='fanyi.web'
data['ue']='UTF-8'
data['action']='FY_BY_CLICKBUTTON'
data['typoResult']='true'
data=urllib.parse.urlencode(data).encode('utf-8')
# 必须对data进行转码

response=urllib.request.urlopen(url,data)
html=response.read().decode('utf-8')

target=json.loads(html)

print('翻译结果:',target['translateResult'][0][0]['tgt'])
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • 1 前言 作为一名合格的数据分析师,其完整的技术知识体系必须贯穿数据获取、数据存储、数据提取、数据分析、数据挖掘、...
    whenif阅读 17,988评论 45 523
  • 本内容为《用Python写网络爬虫》书籍内容,有兴趣的读者可以购买本书,本章的代码皆可在Python3中运行。为了...
    海人为记阅读 2,220评论 0 5
  • Python版本管理:pyenv和pyenv-virtualenvScrapy爬虫入门教程一 安装和基本使用Scr...
    inke阅读 34,681评论 7 93
  • 对电视剧,对读书,对工作,对兴趣,一切都是半拉柯基。读透,读懂,那太慢了。 可是有那么多的东西都想看看,也是浮光掠...
    金地阳光阅读 1,230评论 0 0
  • 曾有朋友和我说过,不谈以后。因为“以后”是由每一个“现在”组成的:如果现在都不能做好,又何来得以后,所以想做的事,...
    向应昌阅读 1,101评论 5 23