使用第三方模块快速抓取与解析:
https://jecvay.com/2015/02/python3-web-bug-series5.html
1.1 抓取指定页面
•#encoding:UTF-8
•importurllib.request
•url ="http://www.baidu.com"
•data= urllib.request.urlopen(url).read()
•data= data.decode('UTF-8')
•print(data)
•解析:urlopen()函数,这个函数返回一个http.client.HTTPResponse对象:
•urllib.request.urlopen(url,
data=None, [timeout, ]*,cafile=None,capath=None,cadefault=False)
[if ppt]•[endif]
•>>>a = urllib.request.urlopen(full_url)>>> type(a)
'http.client.HTTPResponse'>
•>>>a.geturl() # 'http://www.baidu.com/s?word=Jecvay'
•>>>a.info() #
•>>>a.getcode() # 200
1.2 简单处理URL
•importurllib
•importurllib.request
•
•data={}
•data['word']='JecvayNotes'
•
•url_values=urllib.parse.urlencode(data)
•url="http://www.baidu.com/s?"
•full_url=url+url_values
•
•data=urllib.request.urlopen(full_url).read()
•data=data.decode('UTF-8')
•print(data)
•解析:字典data转换为'word=Jecvay+Notes'的字符串
•urllib.parse.urlencode(query,
doseq=False, safe='', encoding=None, errors=None)
•urllib.parse.quote_plus(string,
safe='', encoding=None, errors=None)
2. https://jecvay.com/2014/09/python3-web-bug-series2.html
3.https://jecvay.com/2014/09/python3-web-bug-series3.html
3.1添加超时跳过功能
首先, 我简单地将
urlop = urllib.request.urlopen(url)
改为
urlop = urllib.request.urlopen(url, timeout = 2)
运行后发现, 当发生超时, 程序因为exception中断. 于是我把这一句也放在try .. except 结构里, 问题解决.
3.2 支持自动跳转
在爬 http://baidu.com 的时候, 爬回来一个没有什么内容的东西, 这个东西告诉我们应该跳转到 http://www.baidu.com . 但是我们的爬虫并不支持自动跳转, 现在我们来加上这个功能, 让爬虫在爬 baidu.com 的时候能够抓取 www.baidu.com 的内容.
首先我们要知道爬 http://baidu.com 的时候他返回的页面是怎么样的, 这个我们既可以用 Fiddler 看, 也可以写一个小爬虫来抓取. 这里我抓到的内容如下, 你也应该尝试一下写几行 python 来抓一抓.
3.3伪装浏览器
HTTP 报文分两种:请求报文和响应报文
请求报文的请求行与首部行
GET,POST, HEAD, PUT, DELETE 方法
我用 IE 浏览器访问百度首页的时候, 浏览器发出去的请求报文如下:
GET http://www.baidu.com/ HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Accept-Language: en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
Accept-Encoding: gzip, deflate
Host: www.baidu.com
DNT: 1
Connection: Keep-Alive
Cookie: BAIDUID=57F4D171573A6B88A68789EF5DDFE87:FG=1; uc_login_unique=ccba6e8d978872d57c7654130e714abd; BD_UPN=11263145; BD
然后百度收到这个消息后, 返回给我的的响应报文如下(有删节):
HTTP/1.1 200 OK
Date: Mon, 29 Sep 2014 13:07:01 GMT
Content-Type: text/html; charset=utf-8
Connection: Keep-Alive
Vary: Accept-Encoding
Cache-Control: private
Cxy_all: baidu+8b13ba5a7289a37fb380e0324ad688e7
Expires: Mon, 29 Sep 2014 13:06:21 GMT
X-Powered-By: HPHP
Server: BWS/1.1
BDPAGETYPE: 1
BDQID: 0x8d15bb610001fe79
BDUSERID: 0
Set-Cookie: BDSVRTM=0; path=/
Set-Cookie: BD_HOME=0; path=/
Content-Length: 80137
百度一下,你就知道 ..........这里省略两万字................ 在 GET 的时候添加 header 有很多方法, 下面介绍两种方法.
第一种方法比较简便直接, 但是不好扩展功能, 代码如下:
import urllib.request
url='http://www.baidu.com/'
req=urllib.request.Request(url,headers={
'Connection':'Keep-Alive',
'Accept':'text/html, application/xhtml+xml, */*',
'Accept-Language':'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
'User-Agent':'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko'
})
oper=urllib.request.urlopen(req)
data=oper.read()
print(data.decode())
第二种方法使用了 build_opener 这个方法, 用来自定义 opener, 这种方法的好处是可以方便的拓展功能, 例如下面的代码就拓展了自动处理 Cookies 的功能.
import urllib.request
import http.cookiejar
# head: dict of header
defmakeMyOpener(head={
'Connection':'Keep-Alive',
'Accept':'text/html, application/xhtml+xml, */*',
'Accept-Language':'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
'User-Agent':'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko'
}):
cj=http.cookiejar.CookieJar()
opener=urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
header=[]
forkey,valueinhead.items():
elem=(key,value)
header.append(elem)
opener.addheaders=header
returnopener
oper=makeMyOpener()
uop=oper.open('http://www.baidu.com/',timeout=1000)
data=uop.read()
print(data.decode())
上述代码运行后通过 Fiddler 抓到的 GET 报文如下所示:
GET http://www.baidu.com/ HTTP/1.1
Accept-Encoding: identity
Connection: close
Host: www.baidu.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
Accept: text/html, application/xhtml+xml, */*
Accept-Language: en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3
3.4保存抓回来的报文
顺便说说文件操作. Python 的文件操作还是相当方便的. 我们可以讲抓回来的数据 data 以二进制形式保存, 也可以经过 decode() 处理成为字符串后以文本形式保存. 改动一下打开文件的方式就能用不同的姿势保存文件了. 下面是参考代码:
defsaveFile(data):
save_path='D:\temp.out'
f_obj=open(save_path,'wb')# wb 表示打开方式
f_obj.write(data)
f_obj.close()
# 这里省略爬虫代码
# ...
# 爬到的数据放到 dat 变量里
# 将 dat 变量保存到 D 盘下
saveFile(dat)
4.https://jecvay.com/2014/10/python3-web-bug-series4.html#more-372
5.使用第三方模块快速抓取与解析
https://jecvay.com/2015/02/python3-web-bug-series5.html