當前位置:成語大全網 - 書法字典 - 如何用Python抓取搜索引擎的結果

如何用Python抓取搜索引擎的結果

我選擇抓取百度知道的html作為我的搜索源數據。目前打算先搜索網頁的標題。我選擇了Python scrapy庫來抓取網頁,抓取網頁的標題、url和html,用sqlist3管理抓取的數據源。

爬行過程是深度優先的過程。設置四個初始URL,然後維護壹個數據庫。數據庫中有兩個表和壹個infoLib,存儲了抓取的主要信息:標題、URL和html。另壹個表是urlLib,它存儲已經被抓取的url。它是壹個輔助表。在我們抓取每壹個網頁之前,都需要判斷該網頁是否被抓取過(是否存在於urlLib中)。在數據存儲過程中,使用了少量的SQL語法。因為之前學過MySQL,這壹塊比較好辦。

深度優先的網頁爬取方案是:給定初始url,爬取該網頁中的所有URL,繼續遞歸爬取網頁中的URL。下面逐段分析代碼,方便妳以後復習。

1.構建壹個雜亂的項目:

關於建築工程,妳可以參考這個零碎的入門教程,通過運行:

[python]查看純文本

scrapy startproject ***

在當前目錄下創建壹個scrapy項目,然後在蜘蛛的子目錄下創建壹個. py文件,這是爬蟲的主文件。註意:文件名不能與項目名相同,否則以後調用運行此爬蟲時會出錯。請參見ImportError。

2.編寫。py文件具體來說:

[python]查看純文本

進口廢品

從廢料進口請求

導入sqlite3

類RSS pider(scrapy . spiders . spider):#這個類繼承自scrapy中的spider。

Name = "zhidao" #將爬蟲命名為" Know ",執行爬蟲時對應的指令會是:scrapy crawl zhidao。

#download_delay = 1 #只用來控制爬蟲的速度,1s/時間,可以用來對付反爬蟲。

allowed _ domains =[" zhidao . Baidu . com "]#允許抓取範圍。

Url_first = '/question/' #稍後用於解析域名的短字符串。

start _ URLs =["/question/647795152324593805 . html ",#python

"/question/23976256.html ",#database

"/question/336615223.html ",#C++

"/question/251232779.html ",#操作員系統

"/question/137965104 . html " # Unix編程

] #定義初始url,已知初始網頁有五種類型。

#添加數據庫

conn database = sqlite3 . Connect(" zhidao.db ")#連接到數據庫" zhidao . db "。

c database = conn database . cursor()#設置定位指針。

cDataBase.execute(' ' ' '如果infoLib中不存在,則創建表

(id整數主鍵自動增量,名稱文本,url文本,html文本)“”)

#通過定位指針來操作數據庫。如果zhidao.db中的infoLib表不存在,就會建立,其中主鍵是自增id(引擎的docId),下壹列是文章標題,然後是url,最後是html。

#url數據庫

cDataBase.execute(' ' ' '如果urlLib不存在,則創建表

(url文本主鍵)“”)

#通過定位指針來操作數據庫。如果zhidao.db中的urlLib表不存在,則建立,其中只保存URL,保存爬取的URL。另建表的原因是猜測表的主鍵應該存儲在哈希表中,查詢速度更快。事實上,在這裏也可以將兩個表與壹個外鍵相關聯。

2.2中的解析函數。。py文件:

中的分析函數。py文件將專門處理url返回的響應並解析它。具體守則規定:

[python]查看純文本

定義解析(自身,響應):

pagename = response . XPath('//title/text()')。extract () [0] #解析已爬網網頁中的名稱。

pageUrl = response . XPath("//head/link ")。re('href= "(。*?)" ')[0] #解析抓取的網頁的url,而不是直接用函數獲取,這樣會夾雜亂碼。

page html = response . XPath("//html ")。extract () [0] #獲取網頁html。

#判斷pageUrl是否處於卷曲狀態

如果pageUrl在self.start_urls中:

#如果當前url是start_url的成員。之所以這樣判斷,是因為在重復的start_url中我們還是會爬取網址,但是在非start_url中我們不會爬取已經爬取過的網頁。

self . c database . execute(' SELECT * FROM URL lib其中url =(?)',(pageUrl,))

lines = self.cDataBase.fetchall()

If len(lines): #如果當前Url已被爬網。

Pass #不再向數據庫添加信息,只是不斷向下爬。

否則:#否則,將信息抓取到數據庫中。

self . cdatabase . execute(' INSERT INTO URL lib(URL)VALUES(?)',(pageUrl,))

self . c database . execute(" INSERT INTO infoLib(name,url,html) VALUES(?,?,?)",(頁面名稱,頁面Url,頁面Html))

Else: #此時進入的非url網頁壹定沒有被抓取過(因為會先判斷深入start_url後的網頁,抓取時會在下面的for循環中判斷)。

self . cdatabase . execute(' INSERT INTO URL lib(URL)VALUES(?)',(pageUrl,))

self . c database . execute(" INSERT INTO infoLib(name,url,html) VALUES(?,?,?)",(頁面名稱,頁面Url,頁面Html))

Self.connDataBase.commit() #保存數據庫的更新。

打印“- #輸出提示信息沒用。

for sel in response . XPath('//ul/Li/a ')。re('href="(/question/。*?。html)'): #抓取本頁面所有擴展頁面,判斷並抓取未抓取的頁面。

Sel = ""+sel #解析擴展網頁的url。

self . c database . execute(' SELECT * FROM URL lib其中url =(?)',(sel,))#確定網頁是否已經在數據庫中。

lines = self.cDataBase.fetchall()

如果len(lines) == 0: #如果不是,繼續爬取。

讓步請求(url = sel,callback=self.parse)