urllib:爬取貼吧靜態資料
阿新 • • 發佈:2018-11-09
所謂網頁抓取,就是把URL地址中指定的網路資源從網路流中讀取出來,儲存到本地。 在Python中有很多庫可以用來抓取網頁,其中最常用的就是urllib。
urllib庫的基本使用
- urllib提供了一系列用於操作URL的功能。
- urllib庫是用於操作URL,爬取頁面的python第三方庫,同樣的庫還有requests、httplib2。
- 在Python2.X中,分urllib和urllib2,但在Python3.X中,都統一合併到urllib中。
Python2和Python3區別:urllib
Python2.X |
Python3.X |
urllib |
urllib.request, urllib.error, urllib.parse |
urllib2 |
urllib.request, urllib.error |
urllib2.urlopen |
urllib.request.urlopen |
urllib.urlencode |
urllib.parse.urlencode |
urllib.quote |
urllib.request.quote |
urllib2.Request |
urllib.request.Request |
urlparse |
urllib.parse |
urllib.urlretrieve |
urllib.request.urlretrieve |
urllib2.URLError |
urllib.error.URLError |
cookielib.CookieJar |
http.CookieJar |
GET請求:程式碼模板
匯入request模組
import urllib.request
程式碼模板
# 首先對data進行轉碼,轉化成str型別
data = urllib.parse.urlencode(data)
# URL拼接
new_url = url+"?"+data
result = urllib.request.urlopen(new_url)
# 讀取響應結果
response = result.read()
# 對響應結果解碼
print(response.decode("utf8"))
Get請求:批量爬取貼吧頁面資料
首先我們建立一個python檔案, tiebaSpider.py,我們要完成的是,輸入一個百度貼吧的地址,比如:百度貼吧LOL吧
- 第一頁:http://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=0
- 第二頁: http://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=50
- 第三頁: http://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=100
發現規律了吧,貼吧中每個頁面不同之處,就是url最後的pn的值,其餘的都是一樣的,我們可以抓住這個規律。
簡單寫一個小爬蟲程式,來爬取百度LOL吧的所有網頁。
- 先寫一個main,提示使用者輸入要爬取的貼吧名,並用urllib.urlencode()進行轉碼,然後組合url,假設是lol吧,那麼組合後的url就是:http://tieba.baidu.com/f?kw=lol
# 模擬 main 函式
if __name__ == "__main__":
kw = raw_input("請輸入需要爬取的貼吧:")
# 輸入起始頁和終止頁,str轉成int型別
beginPage = int(raw_input("請輸入起始頁:"))
endPage = int(raw_input("請輸入終止頁:"))
url = "http://tieba.baidu.com/f?"
key = urllib.urlencode({"kw" : kw})
# 組合後的url示例:http://tieba.baidu.com/f?kw=lol
url = url + key
tiebaSpider(url, beginPage, endPage)
- 接下來,我們寫一個百度貼吧爬蟲介面,我們需要傳遞3個引數給這個介面, 一個是main裡組合的url地址,以及起始頁碼和終止頁碼,表示要爬取頁碼的範圍。
def tiebaSpider(url, beginPage, endPage): """ 作用:負責處理url,分配每個url去傳送請求 url:需要處理的第一個url beginPage: 爬蟲執行的起始頁面 endPage: 爬蟲執行的截止頁面 """ for page in range(beginPage, endPage + 1): pn = (page - 1) * 50 filename = "第" + str(page) + "頁.html" # 組合為完整的 url,並且pn值每次增加50 fullurl = url + "&pn=" + str(pn) #print fullurl # 呼叫loadPage()傳送請求獲取HTML頁面 html = loadPage(fullurl, filename) # 將獲取到的HTML頁面寫入本地磁碟檔案 writeFile(html, filename)
- 我們已經之前寫出一個爬取一個網頁的程式碼。現在,我們可以將它封裝成一個小函式loadPage,供我們使用。
def loadPage(url, filename):
'''
作用:根據url傳送請求,獲取伺服器響應檔案
url:需要爬取的url地址
filename: 檔名
'''
print "正在下載" + filename
headers = {"User-Agent": "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;"}
request = urllib2.Request(url, headers = headers)
response = urllib2.urlopen(request)
return response.read()
- 最後如果我們希望將爬取到了每頁的資訊儲存在本地磁碟上,我們可以簡單寫一個儲存檔案的介面。
def writeFile(html, filename):
"""
作用:儲存伺服器響應檔案到本地磁碟檔案裡
html: 伺服器響應檔案
filename: 本地磁碟檔名
"""
print "正在儲存" + filename
with open(filename, 'w') as f:
f.write(html)
print "-" * 20
- 執行程式碼
- 輸出效果
其實很多網站都是這樣的,同類網站下的html頁面編號,分別對應網址後的網頁序號,只要發現規律就可以批量爬取頁面了。
完整程式碼:Python2.7.13
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import urllib
import urllib2
def loadPage(url, filename):
"""
作用:根據url傳送請求,獲取伺服器響應檔案
url: 需要爬取的url地址
filename : 處理的檔名
"""
print "正在下載 " + filename
headers = {"User-Agent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11"}
request = urllib2.Request(url, headers = headers)
return urllib2.urlopen(request).read()
def writePage(html, filename):
"""
作用:將html內容寫入到本地
html:伺服器相應檔案內容
"""
print "正在儲存 " + filename
# 檔案寫入
with open(filename.decode('utf-8'), "w") as f:
f.write(html)
print "-" * 30
def tiebaSpider(url, beginPage, endPage):
"""
作用:貼吧爬蟲排程器,負責組合處理每個頁面的url
url : 貼吧url的前部分
beginPage : 起始頁
endPage : 結束頁
"""
for page in range(beginPage, endPage + 1):
pn = (page - 1) * 50
filename = "第" + str(page) + "頁.html"
fullurl = url + "&pn=" + str(pn)
#print fullurl
html = loadPage(fullurl, filename)
#print html
writePage(html, filename)
print "謝謝使用"
if __name__ == "__main__":
kw = raw_input("請輸入需要爬取的貼吧名:")
beginPage = int(raw_input("請輸入起始頁:"))
endPage = int(raw_input("請輸入結束頁:"))
url = "http://tieba.baidu.com/f?"
key = urllib.urlencode({"kw": kw})
fullurl = url + key
tiebaSpider(fullurl, beginPage, endPage)
def writeFile(html, filename):
"""
作用:儲存伺服器響應檔案到本地磁碟檔案裡
html: 伺服器響應檔案
filename: 本地磁碟檔名
"""
print "正在儲存" + filename
with open(filename, 'w') as f:
f.write(html)
print "-" * 20
完整程式碼:Python3.6.1
import urllib
from urllib import parse
import urllib.request
def loadPage(url, filename):
"""
作用:根據url傳送請求,獲取伺服器響應檔案
url: 需要爬取的url地址
filename : 處理的檔名
"""
print ("正在下載 " + filename)
headers = {"User-Agent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11"}
request = urllib.request.Request(url, headers = headers)
return urllib.request.urlopen(request).read()
def writePage(html, filename):
"""
作用:將html內容寫入到本地
html:伺服器相應檔案內容
"""
print("正在儲存 " + filename)
# 檔案寫入
with open(filename, "wb+") as f:
f.write(html)
print ("-" * 30)
def tiebaSpider(url, beginPage, endPage):
"""
作用:貼吧爬蟲排程器,負責組合處理每個頁面的url
url : 貼吧url的前部分
beginPage : 起始頁
endPage : 結束頁
"""
for page in range(beginPage, endPage + 1):
pn = (page - 1) * 50
filename = "第" + str(page) + "頁.html"
fullurl = url + "&pn=" + str(pn)
#print fullurl
html = loadPage(fullurl, filename)
#print html
writePage(html, filename)
print ("謝謝使用")
if __name__ == "__main__":
kw = input("請輸入需要爬取的貼吧名:")
beginPage = int(input("請輸入起始頁:"))
endPage = int(input("請輸入結束頁:"))
url = "http://tieba.baidu.com/f?"
key = parse.urlencode({"kw": kw})
fullurl = url + key
tiebaSpider(fullurl, beginPage, endPage)
def writeFile(html, filename):
"""
作用:儲存伺服器響應檔案到本地磁碟檔案裡
html: 伺服器響應檔案
filename: 本地磁碟檔名
"""
print ("正在儲存" + filename)
with open(filename, 'w') as f:
f.write(html)
print ("-" * 20)