1. 程式人生 > >urllib:爬取貼吧靜態資料

urllib:爬取貼吧靜態資料

    所謂網頁抓取,就是把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吧

發現規律了吧,貼吧中每個頁面不同之處,就是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)