自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

pyspider爬蟲教程 (2):AJAX和HTTP

開發(fā) 前端
AJAX 的一種常見用法是使用 AJAX 加載 JSON 數(shù)據(jù),然后在瀏覽器端渲染。如果能直接抓取到 JSON 數(shù)據(jù),會比 HTML 更容易解析。

在上一篇教程《pyspider 爬蟲教程 (1):HTML 和 CSS 選擇》中,我們使用 self.crawl API 抓取豆瓣電影的 HTML 內容,并使用 CSS 選擇器解析了一些內容。不過,現(xiàn)在的網站通過使用 AJAX 等技術,在你與服務器交互的同時,不用重新加載整個頁面。但是,這些交互手段,讓抓取變得稍微難了一些:你會發(fā)現(xiàn),這些網頁在抓回來后,和瀏覽器中的并不相同。你需要的信息并不在返回 HTML 代碼中。

在這一篇教程中,我們會討論這些技術 和 抓取他們的方法。

AJAX

AJAX 是 Asynchronous JavaScript and XML(異步的 JavaScript 和 XML)的縮寫。AJAX 通過使用原有的 web 標準組件,實現(xiàn)了在不重新加載整個頁面的情況下,與服務器進行數(shù)據(jù)交互。例如在新浪微博中,你可以展開一條微博的評論,而不需要重新加載,或者打開一個新的頁面。但是這些內容并不是一開始就在頁面中的(這樣頁面就太大了),而是在你點擊的時候被加載進來的。這就導致了你抓取這個頁面的時候,并不能獲得這些評論信息(因為你沒有『展開』)。

AJAX 的一種常見用法是使用 AJAX 加載 JSON 數(shù)據(jù),然后在瀏覽器端渲染。如果能直接抓取到 JSON 數(shù)據(jù),會比 HTML 更容易解析。

當一個網站使用了 AJAX 的時候,除了用 pyspider 抓取到的頁面和瀏覽器看到的不同以外。你在瀏覽器中打開這樣的頁面,或者點擊『展開』的時候,常常會看到『加載中』或者類似的圖標/動畫。例如,當你嘗試抓?。篽ttp://movie.douban.com/explore

 

你會發(fā)現(xiàn)電影是『載入中…』

找到真實的請求

由于 AJAX 實際上也是通過 HTTP 傳輸數(shù)據(jù)的,所以我們可以通過 Chrome Developer Tools 找到真實的請求,直接發(fā)起真實請求的抓取就可以獲得數(shù)據(jù)了。

打開一個新窗口

按 Ctrl+Shift+I (在 Mac 上請按 Cmd+Opt+I) 打開開發(fā)者工具。

切換到網絡( Netwotk 面板)

在窗口中打開 http://movie.douban.com/explore

在頁面加載的過程中,你會在面板中看到所有的資源請求。 

[[191089]] 

AJAX 一般是通過 XMLHttpRequest 對象接口發(fā)送請求的,XMLHttpRequest 一般被縮寫為 XHR。點擊網絡面板上漏斗形的過濾按鈕,過濾出 XHR 請求。挨個查看每個請求,通過訪問路徑和預覽,找到包含信息的請求:http://movie.douban.com/j/searchX61Xsubjects?type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=0

 

在豆瓣這個例子中,XHR 請求并不多,可以挨個查看來確認。但在 XHR 請求較多的時候,可能需要結合觸發(fā)動作的時間,請求的路徑等信息幫助在大量的請求中找到包含信息的關鍵請求。這需要抓取或者前端的相關經驗。所以,有一個我一直在提的觀點,學習抓取的***方法是:學會寫網站。

現(xiàn)在可以在新窗口中打開 http://movie.douban.com/j/searchX67Xsubjects?type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=0,你會看到包含電影數(shù)據(jù)的 JSON 原始數(shù)據(jù)。推薦安裝 JSONView(Firfox版)插件,這樣可以看到更好看的 JSON 格式,展開折疊列等功能。然后,我們根據(jù) JSON 數(shù)據(jù),編寫一個提取電影名和評分的腳本:

  1. class Handler(BaseHandler): 
  2.  
  3.     def on_start(self): 
  4.  
  5.         self.crawl('http://movie.douban.com/j/search_subjects?type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=0'
  6.  
  7.                    callback=self.json_parser) 
  8.  
  9.   
  10.  
  11.     def json_parser(self, response): 
  12.  
  13.         return [{ 
  14.  
  15.             "title": x['title'], 
  16.  
  17.             "rate": x['rate'], 
  18.  
  19.             "url": x['url'
  20.  
  21.         } for x in response.json['subjects']]  

你可以使用 response.json 將結果轉為一個 python 的 dict 對象

你可以在 http://demo.pyspider.org/debug/tutorial_douban_explore 獲得完整的代碼,并進行調試。腳本中還有一個使用 PhantomJS 渲染的提取版本,將會在下一篇教程中介紹。

HTTP

HTTP 是用來傳輸網頁內容的協(xié)議。在前面的教程中,我們已經通過 self.crawl 接口提交了 URL 進行了抓取。這些抓取就是通過 HTTP 協(xié)議傳輸?shù)摹?/p>

在抓取過程中,你可能會遇到類似 403 Forbidden,或者需要登錄的情況,這時候你就需要正確的 HTTP 參數(shù)進行抓取了。

一個典型的 HTTP 請求包如下,這個請求是發(fā)往 http://example.com/ 的:

  1. GET / HTTP/1.1 
  2.  
  3. Host: example.com 
  4.  
  5. Connection: keep-alive 
  6.  
  7. Cache-Control: max-age=0 
  8.  
  9. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 
  10.  
  11. User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.45 Safari/537.36 
  12.  
  13. Referer: http://en.wikipedia.org/wiki/Example.com 
  14.  
  15. Accept-Encoding: gzip, deflate, sdch 
  16.  
  17. Accept-Language: zh-CN,zh;q=0.8 
  18.  
  19. If-None-Match: "359670651" 
  20.  
  21. If-Modified-Since: Fri, 09 Aug 2013 23:54:35 GMT  
  • 請求的***行包含 method, path 和 HTTP 協(xié)議的版本信息
  • 余下的行被稱為 header,是以 key: value 的形式呈現(xiàn)的
  • 如果是 POST 請求,在請求結尾可能還會有 body 內容

你可以通過前面用過的 Chrome Developer Tools 工具查看到這些信息:

 

在大多數(shù)時候,使用正確的 method, path, headers 和 body 總是能抓取到你需要的信息的。

HTTP Method

HTTP Method 告訴服務器對 URL 資源期望進行的操作。例如在打開一個 URL 的時候使用的是 GET 方式,而在提交數(shù)據(jù)的時候一般使用 POST。

TODO: need example here

HTTP Headers

HTTP Headers 是請求所帶的一個參數(shù)列表,你可以在 這里 找到完整的常用 Headers 列表。一些常用的需要注意的有:

User-Agent

UA 是標識你使用的瀏覽器,或抓取程序的一段字符串。pyspider 使用的默認 UA 是 pyspider/VERSION (+http://pyspider.org/)。網站常用這個字符串來區(qū)分用戶的操作系統(tǒng)和瀏覽器,以及判斷對方是否是爬蟲。所以在抓取的時候,常常會對 UA 進行偽裝。

在 pyspider 中,你可以通過 self.crawl(URL, headers={'User-Agent': 'pyspider'}),或者是 crawl_config = {'headers': {'User-Agent': 'xxxx'}} 來指定腳本級別的 UA。詳細請查看 API 文檔。

Referer

Referer 用于告訴服務器,你訪問的上一個網頁是什么。常常被用于防盜鏈,在抓取圖片的時候可能會用到。

X-Requested-With

當使用 XHR 發(fā)送 AJAX 請求時會帶上的 Header,常被用于判斷是不是 AJAX 請求。例如在 北郵人論壇 中,你需要:

  1. def on_start(self): 
  2.  
  3.         self.crawl('http://bbs.byr.cn/board/Python'
  4.  
  5.                    headers={'X-Requested-With''XMLHttpRequest'}, 
  6.  
  7.                    callback=self.index_page)  

帶有 headers={'X-Requested-With': 'XMLHttpRequest'} 才能抓取到內容。

HTTP Cookie

雖然 Cookie 只是 HTTP Header 中的一個,但是因為非常重要,但是拿出來說一下。Cookie 被 HTTP 請求用來區(qū)分、追蹤用戶的身份,當你在一個網站登錄的時候,就是通過寫入 Cookie 字段來記錄登錄狀態(tài)的。

當遇到需要登錄的網站,你需要通過設置 Cookie 參數(shù),來請求需要登錄的內容。Cookie 可以通過開發(fā)者工具的請求面板,或者是資源面板中獲得。在 pyspider 中,你也可以使用 response.cookies 獲得返回的 cookie,并使用 self.crawl(URL, cookie={'key': 'value'}) 來設置請求的 Cookie 參數(shù)。

責任編輯:龐桂玉 來源: Python開發(fā)者
相關推薦

2017-05-10 12:05:17

pyspiderHTMLCSS

2016-11-07 15:23:37

Python

2012-08-08 13:50:28

jQuery

2009-06-23 10:17:09

Ajax事件和錯誤JSF2

2017-08-17 16:00:36

PythonPyspiderHtml5

2015-02-05 09:25:51

HTTPSSPDYHTTP2

2020-03-08 21:22:03

HTTP112

2012-08-31 09:57:08

Ajaxajax開發(fā)開發(fā)

2018-01-30 10:34:24

爬蟲HTTP過程

2019-09-23 08:35:52

2023-09-06 12:01:50

HTTP協(xié)議信息

2024-11-05 08:16:04

HTTP/3HTTP 2.0QUIC

2019-12-13 09:14:35

HTTP2協(xié)議

2021-10-30 19:57:00

HTTP2 HTTP

2019-04-12 10:44:39

2009-06-01 15:44:18

2018-05-14 15:27:06

Python網絡爬蟲爬蟲架構

2019-11-17 22:47:53

HTTP23

2015-10-30 15:42:05

HTTP網絡協(xié)議

2015-08-13 10:31:18

Java 9新功能
點贊
收藏

51CTO技術棧公眾號