爬蟲初探,獲取一個頁面

環境

  • Win7+Python2.7
  • urllib+urllib2

[!] urllib模塊和urllib2模塊的區別

urllib2可以接受一個Request類的實例來設置URL請求的headers,urllib僅可以接受URL。

urllib提供urlencode方法用來GET查詢字符串的產生,而urllib2沒有。

工作流程

定位需要爬取的頁面,糗事百科首頁https://www.qiushibaike.com/

用urllib2的Request類構建一個request

url = "https://www.qiushibaike.com/"
request = urllib2.Request(url)

接下來用urllib2的urlopen方法來請求頁面,並獲取響應(即頁面內容)

response = urllib2.urlopen(request)

打印獲取到的內容

print response.read()

運行我們的腳本,結果報錯了:

Traceback (most recent call last):
  File "00_get_a_page.py", line 19, in <module>
    response = urllib2.urlopen(request)
  File "D:\Python27\lib\urllib2.py", line 154, in urlopen
    return opener.open(url, data, timeout)
  File "D:\Python27\lib\urllib2.py", line 429, in open
    response = self._open(req, data)
  File "D:\Python27\lib\urllib2.py", line 447, in _open
    '_open', req)
  File "D:\Python27\lib\urllib2.py", line 407, in _call_chain
    result = func(*args)
  File "D:\Python27\lib\urllib2.py", line 1241, in https_open
    context=self._context)
  File "D:\Python27\lib\urllib2.py", line 1201, in do_open
    r = h.getresponse(buffering=True)
  File "D:\Python27\lib\httplib.py", line 1121, in getresponse
    response.begin()
  File "D:\Python27\lib\httplib.py", line 438, in begin
    version, status, reason = self._read_status()
  File "D:\Python27\lib\httplib.py", line 402, in _read_status
    raise BadStatusLine(line)
httplib.BadStatusLine: ''

這是因爲糗事百科針對爬蟲的一些反爬優化,必須是瀏覽器才能訪問頁面。

不過沒關係,瀏覽器的信息是通過headers實現的,我們可以用urllib2設置瀏覽器信息頭,把我們的程序僞裝成瀏覽器。

設置頭部驗證信息

user_agent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.75 Safari/537.36 LBBROWSER"
headers = {"User-Agent":user_agent}

可以看到我們設置了User-Agent 這個字段,並將其封裝爲一個字典headers ,後面我們會用到這個headers

user_agent的內容是Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.75 Safari/537.36 LBBROWSER,這個是我是用的獵豹瀏覽器的頭部信息,通過F12開發者工具可以查看到。

重新構造請求,並打印獲取到的響應頁面的內容

request = urllib2.Request(url,headers=headers)

可以發現我們在構造request時除了url參數,還將剛纔封裝好的帶有瀏覽器信息的headers傳給了urllib2.Request的headers參數。

[!] 必須指定headers=headers,否則會默認將headers傳遞給urllib2.Request的第二個參數,但是第二個參數並非headers,如下:

>>> help("urllib2.Request")
Help on class Request in urllib2:
urllib2.Request = class Request
 |  Methods defined here:
 |  __getattr__(self, attr)
 |  __init__(self, url, data=None, headers={}, origin_req_host=None, unverifiable=False)

同樣的再重新請求頁面,獲取響應並打印出來

response = urllib2.urlopen(request)
print response.read()

pic

獲取成功!但是我們的漢字並沒有顯示出來。

這是因爲我們獲取到的response.read()的編碼方式是UTF-8的字節流數據,而我們python2.7的默認編解碼方式爲ASCII,從而導致了亂碼。

我們打印時指定解碼方式爲UTF-8試試看。

print response.read().decode('utf-8')

這裏寫圖片描述

成功!

至此我們獲取了完整的整個頁面信息。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章