可愛的 Python: 使用 mechanize 和 Beautiful Soup 輕松收集 Web 數據

可愛的 Python: 使用 mechanize 和 Beautiful Soup 輕松收集 Web 數據

使用 Python 工具簡化 Web 站點數據的提取和組織

David Mertz, Ph.D., 開發人員, Gnosis Software, Inc.
David Mertz
從 2000 年開始,David Mertz 就一直在為 developerWorks 專欄 Charming PythonXML Matters 撰稿。您可以閱讀他撰寫的書籍 Text Processing in Python。有關 David 的更多信息,請訪問其 個人主頁

簡介:?需要從 Web 頁面收集數據時,可以使用 mechanize 庫自動從 Web 站點收集數據并與之交互。通過 Mechanize 您可以填充表單并設置和保存 cookies,此外,Mechanize 提供了各種各樣的工具來使 Python 腳本具備真正的 Web 瀏覽器的功能,可以與交互式 Web 站點進行交互。一款名為 Beautiful Soup 的常用配套工具幫助 Python 程序理解 Web 站點中包含的臟亂“基本是 HTML” 內容。

查看本系列更多內容

本文的標簽:? python, web

?

?

標記本文!
?

?

發布日期:?2010 年 1 月 18 日
級別:?中級 其他語言版本:?英文
訪問情況?4309 次瀏覽
建議:?0?(添加評論)

1 star2 stars3 stars4 stars5 stars 平均分 (共 2 個評分 )

?

與 David 聯系

David 是我們最受歡迎的和多產的作者之一。查看 David 的個人資料,并與他以及 My developerWorks 上的其他作者和讀者聯系。

使用基本的 Python 模塊,可以 編寫腳本來與 Web 站點交互,但是如果沒有必要的話,那么您就不希望這樣做。Python 2.x 中的模塊 urlliburllib2,以及 Python 3.0 中的統一的 urllib.* 子包,可以在 URL 的末尾獲取資源。然而,當您希望與 Web 頁面中找到的內容進行某種比較復雜的交互時,您需要使用 mechanize 庫(參見 參考資料 獲得下載鏈接)。

在自動化 Web scrap 或用戶與 Web 站點的交互模擬中,最大的困難之一就是服務器使用 cookies 跟蹤會話進度。顯然,cookies 是 HTTP 頭部的一部分,在 urllib 打開資源時會自然顯示出來。而且,標準模塊 Cookie(Python 3 中的 http.cookie)和 cookielib(Python 3 中的 http.cookiejar)有助于在比原始的文本處理更高的層次上處理這些頭部。即使如此,在這個層次上執行處理也非常的繁瑣。mechanize 庫將這種處理提升到一個更高程度的抽象并使您的腳本 — 或交互性 Python shell — 表現出非常類似實際 Web 瀏覽器的行為。

Python 的 mechanize 受到 Perl 的 WWW:Mechanize 的啟發,后者具有類似的一組功能。當然,作為長期的 Python 支持者,我認為 mechanize 更健壯,它看上去似乎繼承了兩種語言的通用模式。

mechanize 的一個親密伙伴是同樣出色的 Beautiful Soup 庫(參見 參考資料 獲得下載鏈接)。這是一個非常神奇的 “粗糙的解析器”,用于解析實際 Web 頁面中包含的有效 HTML。您不需要 將 Beautiful Soup 用于 mechanize,反之亦然,但是多半情況下,當您與 “實際存在的 Web” 交互時,您將希望同時使用這兩種工具。

一個實際示例

我曾在多個編程項目中使用過 mechanize。最近一個項目是從一個流行的 Web 站點中收集匹配某種條件的名稱的列表。該站點提供了一些搜索工具,但是沒有提供任何正式的 API 來執行此類搜索。雖然訪問者可能能夠更明確地猜出我過去在做什么,但我將修改給出的代碼的細節,以避免暴露有關被 scrap 的站點或我的客戶機的過多信息。一般情況下,我給出的代碼對于類似任務是通用的。


入門工具

在實際開發 Web scrap/分析代碼的過程中,我發現以交互式方式查看、處理和分析 Web 頁面的內容以了解相關 Web 頁面實際發生的操作是非常重要的功能。通常,站點中的一些頁面是由查詢動態生成(但是具有一致的模式),或是根據非常嚴格的模板預先生成。

完成這種交互式體驗的一種重要方法就是在 Python shell 內使用 mechanize 本身,特別是在一個增強的 shell 內,比如 IPython(參見 參考資料 獲得一個鏈接)。通過這種方式,您可以在編寫執行希望用于生產中的交互的最終腳本之前,請求各種已鏈接的資源、提交表單、維護或操作站點 cookies,等等。

然而,我發現我與 Web 站點的許多實驗性質的交互在實際的現代 Web 瀏覽器中得到了更好的執行。方便地呈現頁面可以使您更加快速地了解給定頁面或表單中正在發生的事情。問題在于,呈現頁面僅僅完成了事情的一半,可能還不到一半。獲得 “頁面源代碼” 會讓您更進一步。要真正理解給定 Web 頁面或與 Web 服務器的一系列交互的背后的原理,需要了解更多。

要了解這些內容,我常常使用 Firebug(參見 參考資料 獲得鏈接)或面向 Firefox 的 Web Developer 插件(或最新 Safari 版本中的內置的可選 Develop 菜單,但是所針對的目標人群不同)。所有這些工具都可以執行諸如顯示表單字段、顯示密碼、檢查頁面的 DOM、查看或運行 Javascript、觀察 Ajax 通信等操作。比較這些工具的優劣需要另外撰寫一篇文章,但是如果您要進行面向 Web 的編程的話,那么必須熟悉這些工具。

不管使用哪一種工具來對準備實現自動化交互的 Web 站點做實驗,您都需要花比編寫簡潔的 mechanize 代碼(用于執行您的任務)更多的時間來了解站點實際發生的行為。


搜索結果 scraper

考慮到上面提到的項目的意圖,我將把包含 100 行代碼的腳本分為兩個功能:

  • 檢索所有感興趣的結果
  • 從被檢索的頁面中拉取我感興趣的信息

使用這種方式組織腳本是為了便于開發;當我開始任務時,我需要知道如何完成這兩個功能。我覺得我需要的信息位于一個普通的頁面集合中,但是我還沒有檢查這些頁面的具體布局。

首先我將檢索一組頁面并將它們保存到磁盤,然后執行第二個任務,從這些已保存的文件中拉取所需的信息。當然,如果任務涉及使用檢索到的信息構成同一會話內的新交互,那么您將需要使用順序稍微不同的開發步驟。

因此,首先讓我們查看我的 fetch() 函數:


清單 1. 獲取頁面內容
				
import sys, time, os
from mechanize import BrowserLOGIN_URL = 'http://www.example.com/login'
USERNAME = 'DavidMertz'
PASSWORD = 'TheSpanishInquisition'
SEARCH_URL = 'http://www.example.com/search?'
FIXED_QUERY = 'food=spam&' 'utensil=spork&' 'date=the_future&'
VARIABLE_QUERY = ['actor=%s' % actor for actor in('Graham Chapman','John Cleese','Terry Gilliam','Eric Idle','Terry Jones','Michael Palin')]def fetch():result_no = 0                 # Number the output filesbr = Browser()                # Create a browserbr.open(LOGIN_URL)            # Open the login pagebr.select_form(name="login")  # Find the login formbr['username'] = USERNAME     # Set the form valuesbr['password'] = PASSWORDresp = br.submit()            # Submit the form# Automatic redirect sometimes fails, follow manually when neededif 'Redirecting' in br.title():resp = br.follow_link(text_regex='click here')# Loop through the searches, keeping fixed query parametersfor actor in in VARIABLE_QUERY:# I like to watch what's happening in the consoleprint >> sys.stderr, '***', actor# Lets do the actual query nowbr.open(SEARCH_URL + FIXED_QUERY + actor)# The query actually gives us links to the content pages we like,# but there are some other links on the page that we ignorenice_links = [l for l in br.links()if 'good_path' in l.urland 'credential' in l.url]if not nice_links:        # Maybe the relevant results are emptybreakfor link in nice_links:try:response = br.follow_link(link)# More console reporting on title of followed link pageprint >> sys.stderr, br.title()# Increment output filenames, open and write the fileresult_no += 1out = open(result_%04d' % result_no, 'w')print >> out, response.read()out.close()# Nothing ever goes perfectly, ignore if we do not get pageexcept mechanize._response.httperror_seek_wrapper:print >> sys.stderr, "Response error (probably 404)"# Let's not hammer the site too much between fetchestime.sleep(1)

對感興趣的站點進行交互式研究后,我發現我希望執行的查詢含有一些固定的元素和一些變化的元素。我僅僅是將這些元素連接成一個大的 GET 請求并查看 “results” 頁面。而結果列表包含了我實際需要的資源的鏈接。因此,我訪問這些鏈接(當此過程出現某些錯誤時,會拋出 try/except 塊)并保存在這些內容頁面上找到的任何內容。

很簡單,是不是?Mechanize 可以做的不止這些,但是這個簡單的例子向您展示了 Mechanize 的大致功能。


處理結果

現在,我們已經完成了對 mechanize 的操作;剩下的工作是理解在 fetch() 循環期間保存的大量 HTML 文件。批量處理特性讓我能夠在一個不同的程序中將這些文件整齊、明顯地分離開來,fetch()process() 可能交互得更密切。Beautiful Soup 使得后期處理比初次獲取更加簡單。

對于這個批處理任務,我們希望從獲取的各種 Web 頁面的零散內容中生成表式的以逗號分隔的值(CSV)數據。


清單 2. 使用 Beautiful Soup 從無序的內容中生成整齊的數據
				
from glob import glob
from BeautifulSoup import BeautifulSoupdef process():print "!MOVIE,DIRECTOR,KEY_GRIP,THE_MOOSE"for fname in glob('result_*'):# Put that sloppy HTML into the soupsoup = BeautifulSoup(open(fname))# Try to find the fields we want, but default to unknown valuestry:movie = soup.findAll('span', {'class':'movie_title'})[1].contents[0]except IndexError:fname = "UNKNOWN"try:director = soup.findAll('div', {'class':'director'})[1].contents[0]except IndexError:lname = "UNKNOWN"try:# Maybe multiple grips listed, key one should be in theregrips = soup.findAll('p', {'id':'grip'})[0]grips = " ".join(grips.split())   # Normalize extra spacesexcept IndexError:title = "UNKNOWN"try:# Hide some stuff in the HTML <meta> tagsmoose = soup.findAll('meta', {'name':'shibboleth'})[0]['content']except IndexError:moose = "UNKNOWN"print '"%s","%s","%s","%s"' % (movie, director, grips, moose)

第一次查看 Beautiful Soup,process() 中的代碼令人印象深刻。讀者應當閱讀有關文檔來獲得關于這個模塊的更多細節,但是這個代碼片段很好地體現了它的整體風格。大多數 soup 代碼包含一些對只含有格式良好的 HTML 的頁面的 .findAll() 調用。這里是一些類似 DOM 的 .parentnextSiblingpreviousSibling 屬性。它們類似于 Web 瀏覽器的 “quirks” 模式。我們在 soup 中找到的內容并不完全 是一個解析樹。


結束語

諸如我之類的守舊者,甚至于一些更年輕的讀者,都會記住使用 TCL Expect(或使用用 Python 和其他許多語言編寫的類似內容)編寫腳本帶來的愉悅。自動化與 shell 的交互,包括 telnet、ftp、ssh 等等遠程 shell,變得非常的直觀,因為會話中的所有內容都被顯示出來。Web 交互變得更加細致,因為信息被分為頭部和內容體,并且各種相關的資源常常通過 href 鏈接、框架、Ajax 等被綁定在一起。然而,總的來說,您可以 使用 wget 之類的工具來檢索 Web 服務器提供的所有字節,然后像使用其他連接協議一樣運行與 Expect 風格完全相同的腳本。

在實踐中,幾乎沒有編程人員過分執著于過去的老方法,比如我建議的 wget + Expect 方法。Mechanize 保留了許多與出色的 Expect 腳本相同的東西,令人感覺熟悉和親切,并且和 Expect 一樣易于編寫(如果不是更簡單的話)。Browser() 對象命令,比如 .select_form().submit().follow_link(),真的是實現 “查找并發送” 操作的最簡單、最明顯的方法,同時綁定了我們希望在 Web 自動化框架中具備的復雜狀態和會話處理的所有優點。

轉載于:https://www.cnblogs.com/babykick/archive/2011/05/27/2059828.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/275486.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/275486.shtml
英文地址,請注明出處:http://en.pswp.cn/news/275486.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

廣西工學院c語言試題答案,廣西工學院的C語言考試試題

廣西工學院鹿山學院 2005 — 2006 學年第 2 學期課程考核試題 考核課程 《C語言程序設計》 (A卷)考核班級 學生數 印數 考核方式 閉卷 考核時間 120 分鐘一、選擇題(每題2分&#xff0c;共40分)1. 一個C語言的源程序中&#xff0c; 。A&#xff0e;必須有一個主函數2. 下列數據…

JavaScript 斷點調試技巧

大家好&#xff0c;我是若川。最近組織了源碼共度活動&#xff1a;1個月&#xff0c;200人&#xff0c;一起讀了4周源碼&#xff0c;參與的小伙伴都表示收獲很大。如果感興趣可以點擊鏈接掃碼加我微信 ruochuan12。之前推薦過很多次調試文章&#xff0c;說明調試的重要性&#…

大學生電子設計大賽案例分析_為大學生設計問答平臺—案例研究

大學生電子設計大賽案例分析Dealing with academic-related questions like picking a course, fulfilling a major requirement can be tedious and ineffective when you have to simultaneously balance school work, social activities, and focus on personal growth and …

最新最詳細最簡潔Eclipse調試PHP配置詳解(Xdebug,Zend Debugger)

搬家注&#xff1a;該日志寫于2011 年 04 月 07 日&#xff0c;Eclipse&#xff0c;PHP等版本號很多&#xff0c;更新也比較快&#xff0c;請注意文章中的版本。本文不一定幫您解決問題&#xff0c;但能給您一些解決問題的思路及一些概念。 最近開始做SRTP項目WebOS&#xff0c…

按鍵精靈易語言c,求助(把按鍵精靈的源碼轉為易語言的)

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓MoveTo 1203,673IfColor 1203,673,"252489",2 ThenMoveTo 417, 242Delay 10072LeftDown 1LeftClick 1LeftUp 1MoveTo 982, 551Delay 7660LeftDoubleClick 1Delay 10Delay 30LeftUp 1LeftUp 1LeftUp 1MoveTo 1102, 709Del…

入門前端學習路線圖【送書】

大家好&#xff0c;我是若川。記得點上方音頻聽小姐姐配音&#xff0c;超級好聽。華章圖書又贊助了書籍送福利給大家。本次送4本書的抽獎方式是&#xff1a;截止到9月6日&#xff08;周一&#xff09;20:00&#xff0c;在留言區留言任意內容。我會在留言區抽取「1位」關注我公眾…

單選按鈕設置為被選中狀態_為什么要設置錯誤的按鈕狀態

單選按鈕設置為被選中狀態當正確的方法出錯時 (When the right way goes wrong) Let’s say you want to create a click effect on an HTML button. The first idea that many people get is to do something that reproduces the feeling of the sound emitted by a real but…

「娃娃分享」-常見自校檢分析實例.

自校檢是許多軟件的保護手段之一&#xff0c;對軟件加個簡單的殼再增加自校檢在一定程序上可以抵擋住一大部分新手&#xff0c;不過&#xff0c;對許多人來說&#xff0c;這個保護已經很弱了。。下面講幾種常見的解決自校檢方法&#xff0c;寫的粗略&#xff0c;希望大家補充。…

用VC和MinGW導出dll的def和lib(a)文件

為什么80%的碼農都做不了架構師&#xff1f;>>> 原文地址&#xff1a;http://zhangyafeikimi.iteye.com/blog/404580 有了dll文件需要導出def文件&#xff1a; pexports zlib1.dll > zlib1.def 有了dll和def文件&#xff0c;需要導出MinGW的.a文件&#xff1a;…

51中斷編程c語言,[新人求指教]51C語言編程可否用中斷令循環結束提早結束

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓C51_C語言編程控制流水燈硬件電路 p0 接 led 8 個&#xff0c;P33 接按鍵使用中斷2開機燈按1~8逐位閃爍&#xff0c;并循環按鍵后改為 兩燈亮 的流水燈下面寫了個程序#include #include #define uchar unsigned char#define uint u…

產品設計美學案例分析_美學在產品設計中的重要性

產品設計美學案例分析重點 (Top highlight)In one of my previous jobs, I had really interesting debates with the CEO regarding whether we should spend more time improving the way our app looks and feels. ‘How could he not care that the design is outdated?! …

即將到來的ECMAScript 2022標準

大家好&#xff0c;我是若川。周末分享一篇相對簡單的文章。最近組織了源碼共度活動&#xff1a;1個月&#xff0c;200人&#xff0c;一起讀了4周源碼&#xff0c;參與的小伙伴都表示收獲很大。如果感興趣可以點擊鏈接掃碼加我微信 ruochuan12。另外&#xff1a;昨天的推文入門…

c語言中二叉樹中總結點,C語言二叉樹的三種遍歷方式的實現及原理

二叉樹遍歷分為三種&#xff1a;前序、中序、后序&#xff0c;其中序遍歷最為重要。為啥叫這個名字&#xff1f;是根據根節點的順序命名的。比如上圖正常的一個滿節點&#xff0c;A&#xff1a;根節點、B&#xff1a;左節點、C&#xff1a;右節點&#xff0c;前序順序是ABC(根節…

動態庫的創建與使用

1、動態庫文件的創建 &#xff08;1&#xff09;編寫源文件 &#xff08;2&#xff09;編譯生成動態庫 g -fPIC -shared -o libfile_operation.so file_operation.cpp 此編譯過程分為兩步&#xff0c;等同于下面的兩個命令&#xff1a; g -c -fPIC file_operation.cpp …

ux設計中的各種地圖_UX寫作中的移情

ux設計中的各種地圖Demetri Martin is a master of comedic situations. If you’ve never seen Demetri Martin是喜劇情境的大師。 如果你從未見過 him before, he has a sort of dry brand of observational humor, relying more on anecdotes than full stories, and often…

字符串搜索。HOJ1530 Compound Words。

stl set實現字符串搜索。。效率一般。(附二分搜索。) Compound WordsTime limit:1sec.Submitted:233Memory limit:32MAccepted:81Source: Waterloo ACM Programming Contest Sep 28, 1996 You are to find all the two-word compound words in a dictionary. A two-word compo…

字節3-1前端面試官自學Vue的正確姿勢

大家好&#xff0c;我是若川。前不久和一個字節前端TL朋友聊天&#xff0c;說到大廠前端供需脫節的情況。特別是使用Vue框架的&#xff0c;因為簡單易學好上手&#xff0c;但是能夠深入理解的人并不多&#xff0c;大多都只停留在應用層面&#xff0c;缺乏更深層面的理解。尤其是…

android視圖工具,android studio的HierarchyViewer工具如何知道android屏幕的視圖屬性

讓我們首先看看adb是如何組織的.它有3個主要組件,如here所述 –> client – 在用于開發的機器上運行的客戶端.通過發出adb命令從shell調用客戶端.層次結構查看器還會創建adb客戶端.> server – 在開發計算機上作為后臺進程運行的服務器.它將從adb客戶端發出的命令傳遞給a…

云時代架構讀后感4--IT架構的本質

IT架構的本質 原文地址&#xff1a;http://mp.weixin.qq.com/s?__bizMzAwNTQ4MTQ4NQ&mid2453562304&idx1&snbe86a7bc682c4e76e06b87a10ad45188&chksm8cd136a2bba6bfb430103e50f94b670e799412d0a1cae4eded0eb901847b6d462359ae317635&mpshare1&scene23…

蘋果風格ui_蘋果如何使Soft-UI成為未來

蘋果風格ui重點 (Top highlight)Apple announced some pretty wild updates at WWDC 2020 today.蘋果今天在WWDC 2020上宣布了一些相當瘋狂的更新。 But technology aside, let’s focus on how their UI has changed. It went through the first bitmap representations, thr…