使用第三方模塊快速抓取與解析:
https://jecvay.com/2015/02/python3-web-bug-series5.html
1.Python 3開發(fā)網(wǎng)絡(luò)爬蟲(一)
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()函數(shù)胎源,這個函數(shù)返回一個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轉(zhuǎn)換為'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)
運行后發(fā)現(xiàn), 當發(fā)生超時, 程序因為exception中斷. 于是我把這一句也放在try .. except 結(jié)構(gòu)里, 問題解決.
3.2?支持自動跳轉(zhuǎn)
在爬 http://baidu.com 的時候, 爬回來一個沒有什么內(nèi)容的東西, 這個東西告訴我們應(yīng)該跳轉(zhuǎn)到 http://www.baidu.com . 但是我們的爬蟲并不支持自動跳轉(zhuǎn), 現(xiàn)在我們來加上這個功能, 讓爬蟲在爬 baidu.com 的時候能夠抓取 www.baidu.com 的內(nèi)容.
首先我們要知道爬 http://baidu.com 的時候他返回的頁面是怎么樣的, 這個我們既可以用 Fiddler 看, 也可以寫一個小爬蟲來抓取. 這里我抓到的內(nèi)容如下, 你也應(yīng)該嘗試一下寫幾行 python 來抓一抓.
3.3偽裝瀏覽器
HTTP 報文分兩種:請求報文和響應(yīng)報文
請求報文的請求行與首部行
GET,POST, HEAD, PUT, DELETE 方法
我用 IE 瀏覽器訪問百度首頁的時候, 瀏覽器發(fā)出去的請求報文如下:
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
然后百度收到這個消息后, 返回給我的的響應(yīng)報文如下(有刪節(jié)):
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 的文件操作還是相當方便的. 我們可以講抓回來的數(shù)據(jù) data 以二進制形式保存, 也可以經(jīng)過 decode() 處理成為字符串后以文本形式保存. 改動一下打開文件的方式就能用不同的姿勢保存文件了. 下面是參考代碼:
defsaveFile(data):
save_path='D:\temp.out'
f_obj=open(save_path,'wb')# wb 表示打開方式
f_obj.write(data)
f_obj.close()
# 這里省略爬蟲代碼
# ...
# 爬到的數(shù)據(jù)放到 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