1. 程式人生 > >Python爬蟲開發【第1篇】【urllib2】

Python爬蟲開發【第1篇】【urllib2】

返回JSON數據 驗證 ajax 本地磁盤 發送請求 doc 大寫 總結 錯誤

1、urlopen

# urllib2_urlopen.py

# 導入urllib2 庫
import urllib2

# 向指定的url發送請求,並返回服務器響應的類文件對象
response = urllib2.urlopen("http://www.baidu.com")

# 類文件對象支持 文件對象的操作方法,如read()方法讀取文件全部內容,返回字符串
html = response.read()

# 打印字符串
print html
執行寫的python代碼,將打印結果

Power@PowerMac ~$: python urllib2_urlopen.py

2、request

# urllib2_request.py

import urllib2

# url 作為Request()方法的參數,構造並返回一個Request對象
request = urllib2.Request("http://www.baidu.com")

# Request對象作為urlopen()方法的參數,發送給服務器並接收響應
response = urllib2.urlopen(request)

html = response.read()

print html

3、user_agent(用戶代理)

#urllib2_useragent.py

import urllib2

url = "http://www.itcast.cn"

#IE 9.0 的 User-Agent,包含在 ua_header裏
ua_header = {"User-Agent" : "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;"} 

#  url 連同 headers,一起構造Request請求,這個請求將附帶 IE9.0 瀏覽器的User-Agent
request = urllib2.Request(url, headers = ua_header)

# 向服務器發送這個請求
response = urllib2.urlopen(request)

html = response.read()
print html

4、更多Header信息

在 HTTP Request 中加入特定的 Header,來構造一個完整的HTTP請求消息。

添加一個特定的header
# urllib2_headers.py

import urllib2

url = "http://www.itcast.cn"

#IE 9.0 的 User-Agent
header = {"User-Agent" : "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;"} 
request = urllib2.Request(url, headers = header)

#也可以通過調用Request.add_header() 添加/修改一個特定的header
request.add_header("Connection", "keep-alive")

# 也可以通過調用Request.get_header()來查看header信息
# request.get_header(header_name="Connection")

response = urllib2.urlopen(req)

print response.code     #可以查看響應狀態碼
html = response.read()

print html

隨機添加/修改User-Agent
# urllib2_add_headers.py import urllib2 import random url = "http://www.itcast.cn" ua_list = [ "Mozilla/5.0 (Windows NT 6.1; ) Apple.... ", "Mozilla/5.0 (X11; CrOS i686 2268.111.0)... ", "Mozilla/5.0 (Macintosh; U; PPC Mac OS X.... ", "Mozilla/5.0 (Macintosh; Intel Mac OS... " ] user_agent = random.choice(ua_list) request = urllib2.Request(url) #也可以通過調用Request.add_header() 添加/修改一個特定的header request.add_header("User-Agent", user_agent) # 第一個字母大寫,後面的全部小寫 request.get_header("User-agent") response = urllib2.urlopen(req) html = response.read() print html

5、urllib和urllib2

  • urllib 僅可以接受URL,不能創建 設置了headers 的Request 類實例
  • urllib 提供 urlencode 方法用來GET查詢字符串的產生,而 urllib2 則沒有
  • 編碼使用urllib的urlencode()函數,幫我們將key:value這樣的鍵值對轉換成"key=value"這樣的字符串,解碼使用urllib的unquote()函數

6、GET請求:用於我們向服務器獲取數據

批量抓取貼吧頁面數據

# 模擬 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

總結:

GET請求爬蟲過程
# urllib2_get.py

import urllib      #負責url編碼處理
import urllib2

url = "http://www.baidu.com/s"
word = {"wd":"傳智播客"}
word = urllib.urlencode(word) #轉換成url編碼格式(字符串)
newurl = url + "?" + word    # url首個分隔符就是 ?

headers={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) 
      Chrome/51.0.2704.103 Safari/537.36"}
# 發送請求 request = urllib2.Request(newurl, headers=headers)   # 獲取響應 response = urllib2.urlopen(request) print response.read()

7、POST請求:Request請求對象的裏有data參數,它就是用在POST裏的,我們要傳送的數據就是這個參數data,data是一個字典,裏面要匹配鍵值對

import urllib
import urllib2

# POST請求的目標URL
url = "http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=null"

headers={"User-Agent": "Mozilla...."}

formdata = {
    "type":"AUTO",
    "i":"i love python",
    "doctype":"json",
    "xmlVersion":"1.8",
    "keyfrom":"fanyi.web",
    "ue":"UTF-8",
    "action":"FY_BY_ENTER",
    "typoResult":"true"
}

data = urllib.urlencode(formdata)

request = urllib2.Request(url, data = data, headers = headers)
response = urllib2.urlopen(request)

print response.read()
發送POST請求時,需要特別註意headers的一些屬性:
  • Content-Length: 144: 是指發送的表單數據長度為144,也就是字符個數是144個。
  • X-Requested-With: XMLHttpRequest :表示Ajax異步請求。
  • Content-Type: application/x-www-form-urlencoded : 表示瀏覽器提交 Web 表單時使用,表單數據會按照 name1=value1&name2=value2 鍵值對形式進行編碼。

8、獲取AJAX加載的內容

有些網頁內容使用AJAX加載,AJAX一般返回的是JSON,直接對AJAX地址進行post或get,就返回JSON數據

import urllib
import urllib2

# demo1

url = "https://movie.douban.com/j/chart/top_list?type=11&interval_id=100%3A90&action"

headers={"User-Agent": "Mozilla...."}

# 變動的是這兩個參數,從start開始往後顯示limit個
formdata = {
    start:0,
    limit:10
}
data = urllib.urlencode(formdata)

request = urllib2.Request(url, data = data, headers = headers)
response = urllib2.urlopen(request)

print response.read()


# demo2

url = "https://movie.douban.com/j/chart/top_list?"
headers={"User-Agent": "Mozilla...."}

# 處理所有參數
formdata = {
    type:11,
    interval_id:100:90,
    action:‘‘,
    start:0,
    limit:10
}
data = urllib.urlencode(formdata)

request = urllib2.Request(url, data = data, headers = headers)
response = urllib2.urlopen(request)

print response.read()

9、處理HTTPS請求 SSL證書驗證

https 開頭的網站,urllib2可以為 HTTPS 請求驗證SSL證書,就像web瀏覽器一樣,如果網站的SSL證書是經過CA認證的,則能夠正常訪問

如果SSL證書驗證不通過,或者操作系統不信任服務器的安全證書,比如瀏覽器在訪問12306網站如:https://www.12306.cn/mormhweb/的時候,

會警告用戶證書不受信任。

urllib2在訪問的時候則會報出SSLError:

import urllib2

url = "https://www.12306.cn/mormhweb/"

headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) 
        Chrome/54.0.2840.99 Safari/537.36
"} request = urllib2.Request(url, headers = headers) response = urllib2.urlopen(request) print response.read() 運行結果: urllib2.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)> 所以,如果以後遇到這種網站,我們需要單獨處理SSL證書,讓程序忽略SSL證書驗證錯誤,即可正常訪問。 import urllib import urllib2 # 1. 導入Python SSL處理模塊 import ssl # 2. 表示忽略未經核實的SSL證書認證 context = ssl._create_unverified_context() url = "https://www.12306.cn/mormhweb/" headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
        Chrome/54.0.2840.99 Safari/537.36"} request = urllib2.Request(url, headers = headers) # 3. 在urlopen()方法裏 指明添加 context 參數 response = urllib2.urlopen(request, context = context) print response.read()

Python爬蟲開發【第1篇】【urllib2】