1. 程式人生 > >[python網路爬蟲]表單和登陸爬蟲

[python網路爬蟲]表單和登陸爬蟲

當你想編寫更為複雜的網頁爬蟲的時候,你面臨的第一個問題也許會是:“如何獲取登陸頁面後的資訊?”,因為網路已經飛快地向互動、社交媒體、使用者生成內容方向發展。表格和登陸就成為這些型別網站幾乎不可或缺的主要組成。幸運的是,表單和登陸還是相對比較容易處理的。

截至當前,在我們之前的爬蟲示例中,絕大部分與伺服器的互動都是採用了HTTP GET方式去獲取資訊的。而在本章,我們所關注的是如何通過POST方式來向伺服器提交資訊用於儲存和分析。

表單給使用者提供了一種伺服器可以理解並使用的,提交POST請求的簡單方法。就像網址連結可以幫助使用者格式化GET請求,HTML表單可以幫使用者格式化POST請求。當然通過一小段程式碼,我們就可以輕鬆的通過爬蟲來建立並提交表單。

Python Requests類庫

儘管可以通過Python核心類庫來操作網頁表單,但有些時候更友好的程式碼可以讓生活更美好。當你開始使用urllib類庫的GET請求做更多事情的時候,放眼Python核心庫之外也許更有幫助。

Requests類庫在處理複雜HTTP請求、Cookies,請求頭等方面更為高效,此處便是Requests類庫的建立者Kenneth Reitz對Python核心工具的評價:

Python標準urlib2模組提供了你所需要的絕大多數HTTP功能,但是其API卻很垃圾。它的建立是用於不同時間以及不同網頁的,即使執行一個簡單的任務也需要大量的工作(甚至重寫方法等)。

事情並不應該如此,至少在Python中不應如此。

和其他Python類庫一樣,Requests類庫可以通過Python第三方類庫管理器如pip來安裝,或者直接下載原始碼進行安裝。

提交一個簡單表單

絕大多數網頁表單由部分HTML標籤、提交按鈕以及一個Action頁(具體執行表單任務的網址)所組成。HTML標籤一般含有文字標籤不過有時候也包含檔案上傳或其他非文字內容標籤。

大多數熱門網站在robots.txt檔案中遮蔽了針對登入表單的訪問(詳見附錄C),因此為了更安全的玩耍,我在pythonscraping.com上建立了一系列不同型別的表單和登入頁面。你可以執行你的爬蟲來訪問他們。其中最為簡單的表單地址為:http://bit.ly/1AGKPRU

完整表單程式碼如下:

<formmethod="post"action="processing.php">
First name: <inputtype="text"name="firstname"><br>
Last name: <inputtype="text"name="lastname"><br><inputtype="submit"value="Submit"></form>

在此處需要注意的是:第一,兩個input標籤的名稱為firstnamelastname。這個非常重要,這些標籤的名稱決定了要POST到伺服器的表格變數的名稱。如果你要模擬提交表格,並提交自定義內容,那麼你需要確定你的變數名稱與標籤名稱匹配。

第二需要注意的是表格實際提交到的執行頁面是processing.php(絕對路徑為:http://bit.ly/1d7TPVk)。任何POST請求提交到表單都是上述(Action所指向的)地址,而不是包含表單的頁面地址。記住:HTML表單的主要目的僅是幫助網站訪問者格式化提交到處理頁面的請求。除非你在研究如何格式化請求,那麼你完全沒有必要被包含表單的頁面所困擾。

通過Requests類庫提交一個表單可以使用4行程式碼完成,包括import以及print內容函式。

import requests
params={'firstname':'Ryan','lastname':'Mitchell'}
r = requests.post("http://pythonscraping.com/pages/files/processing.php", data=params)print(r.text)

表單提交後,指令碼會返回頁面內容:

Hello there,RyanMitchell!

這個指令碼可以被應用到許多網際網路上的簡單表單。例如,登入O‘Reilly媒體通訊的表單,如下所示:

<formaction="http://post.oreilly.com/client/o/oreilly/forms/
          quicksignup.cgi"id="example_form2"method="POST"><inputname="client_token"type="hidden"value="oreilly"/><inputname="subscribe"type="hidden"value="optin"/><inputname="success_url"type="hidden"value="http://oreilly.com/store/
                 newsletter-thankyou.html"/><inputname="error_url"type="hidden"value="http://oreilly.com/store/
                 newsletter-signup-error.html"/><inputname="topic_or_dod"type="hidden"value="1"/><inputname="source"type="hidden"value="orm-home-t1-dotd"/><fieldset><inputclass="email_address long"maxlength="200"name="email_addr"size="25"type="text"value="Enter your email here"/><buttonalt="Join"class="skinny"name="submit"onclick="return addClickTracking('orm','ebook','rightrail','dod');"value="submit">Join</button></fieldset></form>

儘管第一次開起來上述程式碼有點嚇人,不過要記住在絕大多數案例中(我們稍後會講到其他例外),你只需要關注兩個事情:

新增需要的資訊並執行:

import requests
params={'email_addr':'[email protected]'}
r = requests.post("http://post.oreilly.com/client/o/oreilly/forms/
                   quicksignup.cgi", data=params)print(r.text)

在這個例子中,當你可以真正進入O'Reilly的郵件列表前,網站返回了另一個需要填寫的表單。不過同樣的原理可以應用到這個新表單上。不過,當你在家自己嘗試的時候,我需要你保證正當利用這個技術,而不是通過無效註冊給釋出者製造垃圾郵件。

單選、多選和其他輸入元件

很顯然,並不是所有表單都是由文字標籤加提交按鈕所組成。標準的HTML包含多種表單輸入欄位:單選按鈕、多選按鈕、下拉框等等。在HTML5中則擴充了滑動條、郵件、日期等。而且通過自定義Javascript還為輸入欄位帶來了無限可能的擴充,如顏色選擇、日曆等,只要程式設計師想去做就沒有不能實現的。

不管上述表單欄位看起來有多麼的複雜,你真正需要關心的只有兩個東西:元素的名稱和它的數值。元素的名稱可以通過檢視原始碼並找到name屬性來輕鬆辨別。元素數值的獲取則稍微有點麻煩,因為它可能在表單提交前瞬間通過Javascript生成。以相當獨特的顏色拾取器為例,它的數值就有可能是#F03030這樣的資料。

如果你不確定輸入欄位數值的格式,這裡有一些工具你可以用來跟蹤瀏覽器和網站之間的GETPOST請求。最好也是最直觀的辦法就是檢視GET請求,就像之前提到的檢視網站URL。如果網站的URL類似下面:

http://domainname.com?thing1=foo&thing2=bar

那你就知道對應的表單應該是如下形式的:

<formmethod="GET"action="someProcessor.php"><inputtype="someCrazyInputType"name="thing1"value="foo"/><inputtype="anotherCrazyInputType"name="thing2"value="bar"/><inputtype="submit"value="Submit"/></form>

對應的Python引數物件就是:

{'thing1':'foo','thing2':'bar'}

如圖9-1所示。

如果你被看起來很複雜的POST表單所困擾,同時還想檢視瀏覽器給伺服器,傳送的到底是什麼引數的話。那麼最簡單的方法就是使用瀏覽器的監視或開發者工具來檢視它們。

谷歌瀏覽器(Chrome)開發者工具可以通過【檢視】->【開發】->【開發者工具】來開啟。開發者工具列出了你瀏覽器與當前網站的所有訪問請求,並且可以檢視所有請求的訪問詳情。

提交檔案和圖片

儘管檔案上傳在網際網路中十分普遍,但是在網路爬蟲中卻不是十分常用。不過你可以自己編寫指令碼在你的網站上測試檔案上傳。不管怎樣,知道如何上傳檔案總是有用的。

<formaction="processing2.php"method="post"enctype="multipart/form-data">
    Submit a jpg, png, or gif: <inputtype="file"name="image"><br><inputtype="submit"value="Upload File"></form>

除了<input>標籤的file型別欄位,它看起來和之前例子中的文字表單類似。幸運的是,通過Python的requests類庫操作表單也是極為類似的:

import requests
files ={'uploadFile': open('../files/Python-logo.png','rb')}
r = requests.post("http://pythonscraping.com/pages/processing2.php",  files=files)print(r.text)

可以看到替換了之前的簡單字串,現在提交到表單欄位的數值(通過名稱uploadFile)是Python的檔案物件,通過open函式返回的。在這個例子中,我提交了一個儲存在本地的一個影象檔案,路徑為:../files/Python-logo.png,相對於當前執行的Python指令碼。

是的,就是這麼簡單!

處理登陸和Cookies

到目前為止,我們討論的表單都只允許你提交資訊到網站,或者查看錶單提交後返回頁面所包含的資訊。這些與登陸表單,可以讓你保持登陸狀態訪問網站有何異同呢?

絕大多數現代網站使用Cookies來辨別登陸者的狀態。一旦網站驗證通過你的登陸資訊,它便會在你的瀏覽器中儲存一個Cookie值,其包含伺服器生成的Token、過期時間以及跟蹤資訊等內容。當你訪問網站任意頁面的時候,網站則通過Cookie來作為訪問者的授權標誌。在90年代中期,Cookie尚未大規模使用前,如何安全驗證並且跟蹤訪問者身份對於網站來說是一個大麻煩。

儘管Cookies對於網路開發者來說是一個非常好的解決方案,不過對於網路爬蟲卻造成了不小的困難。你可以不斷嘗試提交登陸表格,不過如果你沒有處理好登陸表單返回的Cookie資訊,那麼當你訪問下一個頁面的時候,你所表現的就好像從來沒有登陸過。

我建立了一個簡單的登陸表單:http://bit.ly/1KwvSSG(使用者名稱可以任意輸入,不過密碼必須是"password"

如果你在沒有登陸的情況下訪問歡迎頁面或者個人資料頁面,你會得到一個錯誤資訊以及登陸操作指引。在個人資訊頁面,會檢查你瀏覽器Cookie資訊,判斷其是否是來自登陸頁面設定。

通過Requests類庫來跟蹤處理Cookies資訊非常簡單:

import requests

params={'username':'Ryan','password':'password'}
r = requests.post("http://pythonscraping.com/pages/cookies/welcome.php",params)print("Cookie is set to:")print(r.cookies.get_dict())print("-----------")print("Going to profile page...")
r = requests.get("http://pythonscraping.com/pages/cookies/profile.php", 
                 cookies=r.cookies)print(r.text)

此處我向歡迎頁面傳送了登陸引數,就像在登入表單處理時的一樣。我在得到返回的Cookies後,將其打印出來驗證,並且通過設定cookies引數傳送到個人資訊頁面。

對於簡單情況上述方式表現挺好,不過如果你要處理更為複雜的網站,例如在沒有提醒的情況下頻繁更新Cookies資訊,或者你一開始根本就不去考慮Cookies操作。使用Requests類庫的session函式在這種例子中表現更好:

import requests

session = requests.Session()params={'username':'username','password':'password'}
s = session.post("http://pythonscraping.com/pages/cookies/welcome.php",params)print("Cookie is set to:")print(s.cookies.get_dict())print("-----------")print("Going to profile page...")
s = session.get("http://pythonscraping.com/pages/cookies/profile.php")print(s.text)

在這個例子中,session物件(通過執行requests.Session()獲得)負責跟蹤處理session資訊,如Cookies、請求頭,甚至包括在HTTP上執行的協議如HTTPAdapters。

Requests是一個非常棒的類庫,其健全的功能甚至不需要程式設計師去思考如何編寫,第二個類似的類庫可能就是Selenium(我們將在第十章詳述)。儘管將所有工作交給類庫去處理省事省力,但是非常重要的就是搞清楚Cookies是什麼以及在編寫網路爬蟲時如何去正確操作Cookies。它會節省很多痛苦除錯的時間,或者幫你弄清楚為何網站有奇怪的表現。



相關推薦

[python網路爬蟲]登陸爬蟲

當你想編寫更為複雜的網頁爬蟲的時候,你面臨的第一個問題也許會是:“如何獲取登陸頁面後的資訊?”,因為網路已經飛快地向互動、社交媒體、使用者生成內容方向發展。表格和登陸就成為這些型別網站幾乎不可或缺的主要組成。幸運的是,表單和登陸還是相對比較容易處理的。 截至當前,在我們之

Flask(python web) 處理Ajax請求

1.處理表單(form) 首先,編一個簡單的html登入頁面(名字為login.html(根路由jinjia2模板指定)): <html> <head> <meta charset="UTF_8"> <meat lang=

python網路爬蟲——互動

將與網頁進行互動,根據使用者輸入返回對應的內容。有些網站需要在登入後才能訪問某個網頁,在登入之前不允許訪問。所以使用使用者表單互動傳遞引數登入。 表單方法 HTML定義了兩種向伺服器提交資料的方法,分別是GET和POST。使用GET時,會將類似?name1=va

Python - 爬蟲爬取登陸github

用API搜尋GitHub中star數最多的前十個庫,並用post方法登陸並點選收藏 一 用API搜尋GitHub中star數最多的前十個庫 利用GitHub提供的API爬取前十個star數量最多的Python庫     GitHub提供了很多專門為爬蟲準

python爬蟲爬取登陸github

一 利用API簡單爬取 利用GitHub提供的API爬取前十個star數量最多的Python庫 GitHub提供了很多專門為爬蟲準備的API介面,通過介面可以爬取到便捷,易處理的資訊。(這是GitHub官網的各種api介紹)     使用到的庫 import re

python爬蟲-->互動

前幾篇博文中,我們的程式下載的靜態網頁總是返回相同的內容。在本篇博文中,我們將與網頁進行互動,根據使用者輸入返回對應的內容。 本篇博文將主要介紹以下兩種方式進行表單互動 使用cookie登入網頁,更新網頁內容(較麻煩) 使用Mechanize模組實現自動化

java sql編輯器 動態報表 數據庫備份還原 quartz定時任務調度 自定義 java圖片爬蟲

springmvcmybatis整合 bootstrap 框架源碼 spring html5 官網 http://www.fhadmin.org/A代碼編輯器,在線模版編輯,仿開發工具編輯器,pdf在線預覽,文件轉換編碼B 集成代碼生成器 [正反雙向](單表、主表、明細表、樹形表,快速開

java sql 編輯器 數據庫備份還原 quartz 定時任務調度 自定義 java 圖片爬蟲 集成代碼生成器

分離 文件大小 發送郵件 進度條 服務器配置 mysql http 備份數據庫 生成報表 A代碼編輯器,在線模版編輯,仿開發工具編輯器,pdf在線預覽,文件轉換編碼B 集成代碼生成器 [正反雙向](單表、主表、明細表、樹形表,快速開發利器)+快速表單構建器 freemake

【極客學院】-python學習筆記-3-執行緒爬蟲 (request安裝遇到問題及解決,應用requests提取資訊)

極客學院課程網址:http://www.jikexueyuan.com/course/821_2.html?ss=1 任務: 爬取極客學院官方網站的課程庫,並儲存 Requests介紹與安裝: HTTP for Humans Python的第三方庫,實現網頁連結,更自動

ASP.NET MVC5(三):HTML輔助方法

http get 暴露 sta 選擇 .text 響應 pos 多行文本 二進制 表單的使用 Action和Method特性   Action特性用以告知瀏覽器信息發往何處,因此,Action特性後面需要包含一個Url地址。這裏的Url地址可以是相對的,也可以是絕對的。如

HTML組件

date min ber 用戶 http請求 實現 form表單 搜索框 isa 表單 基本所有的網頁無非就是在做兩件事情:1.呈現數據給客戶看,2.接收用戶輸入的數據。所以表單就是用來收集用戶輸入的數據,然後提交給服務器。示例圖: 表單在網頁中主要負責數據采集功能,一個

Asp.net MVC4高級編程學習筆記-模型學習第五課MVCHTML輔助方法20171101

流量 取值 工作 sin 輔助 一個點 大量 元數據 view MVC表單和HTML輔助方法 一、表單的使用。 表單中的action與method特性。Action表示表單要提交往那裏,因此這裏就有一個URL。這個URL可以是相對或絕對地址。表單默認的method屬性值是g

(十二)easyUI之驗證完成登錄頁面

() 成功 options 表單提交 odi 1-1 java ima 1.4 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

formajax上傳文件

open 進制數 一行 pan oct art span 知識點 charset 使用form表單上傳文件 知識點/註意點 from表單裏 要加上這行 enctype="multipart/form-data" 上傳文件 上傳的是二進制數據 用request.FI

【ASP.NET MVC系列】淺談HTML輔助方法

繼承 好的 內容 概述 調用 復制 畫圖 models pac 【01】淺談Google Chrome瀏覽器(理論篇) 【02】淺談Google Chrome瀏覽器(操作篇)(上) 【03】淺談Google Chrome瀏覽器(操作篇)(下) 【04】淺談AS

css總結18:HTML 輸入

進行 ons 單選 允許 word pan 通過 定義 file 1 HTML 表單和輸入 1.1 HTML 表單介紹 表單是一個包含表單元素的區域。 表單元素是允許用戶在表單中輸入內容,比如:文本域(textarea)、下拉列表、單選框(radio-buttons)、復選

學習日記13、ajax同時提交from多個參數

表單 reload log DC change AD UC sca col if ($("form").valid()) { $.ajax({ url: "@Url.Action("EditCusAndCusCard")"

第二天 第二彈 iframe內嵌框架 frominput的運用

tex class AC -s AI bsp box 內嵌 align 先是iframe框架 接下來是代碼的運用 <html> <head> <title>IFRAME</title> <meta charset

Django框架 之 FormAjax上傳文件

不可 _for render ren files AS AD 什麽 OS 瀏覽目錄 Form表單上傳文件 Ajax上傳文件 偽造Ajax上傳文件 Form表單上傳文件 html <h3>form表單上傳文件&

ionic-CSS:ionic 輸入框

輸入框 hit col 標簽 字段 head wid AS wrapper ylbtech-ionic-CSS:ionic 表單和輸入框 1.返回頂部 1、 ionic 表單和輸入框 list 類同樣可以用於 input 元素。item-in