小編給大家分享一下Python怎么實現(xiàn)簡易Web爬蟲,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
成都創(chuàng)新互聯(lián)是專業(yè)的金堂縣網(wǎng)站建設(shè)公司,金堂縣接單;提供成都做網(wǎng)站、成都網(wǎng)站制作,網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進行金堂縣網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團隊,希望更多企業(yè)前來合作!簡介:
網(wǎng)絡(luò)爬蟲(又被稱為網(wǎng)頁蜘蛛),網(wǎng)絡(luò)機器人,是一種按照一定的規(guī)則,自動地抓信息的程序或者腳本。假設(shè)互聯(lián)網(wǎng)是一張很大的蜘蛛網(wǎng),每個頁面之間都通過超鏈接這根線相互連接,那么我們的爬蟲小程序就能夠通過這些線不斷的搜尋到新的網(wǎng)頁。
Python作為一種代表簡單主義思想的解釋型、面向?qū)ο?、功能強大的高級編程語言。它語法簡潔并且具有動態(tài)數(shù)據(jù)類型和高層次的抽象數(shù)據(jù)結(jié)構(gòu),這使得它具有良好的跨平臺特性,特別適用于爬蟲等程序的實現(xiàn),此外Python還提供了例如Spyder這樣的爬蟲框架,BeautifulSoup這樣的解析框架,能夠輕松的開發(fā)出各種復(fù)雜的爬蟲程序。
在這篇文章中,使用Python自帶的urllib和BeautifulSoup庫實現(xiàn)了一個簡單的web爬蟲,用來爬取每個URL地址及其對應(yīng)的標(biāo)題內(nèi)容。
流程:
爬蟲算法從輸入中讀取的一個URL作為初始地址,向該地址發(fā)出一個Request請求。
請求的地址返回一個包含所有內(nèi)容的,將其存入一個String變量,使用該變量實例化一個BeautifulSoup對象,該對象能夠?qū)?nèi)容并且將其解析為一個DOM樹。
根據(jù)自己的需要建立正則表達式,最后借助HTML標(biāo)簽從中解析出需要的內(nèi)容和新的URL,將新的放入隊列中。
對于目前所處的URL地址與爬去的內(nèi)容,在進行一定的過濾、整理后會建立索引,這是一個單詞-頁面的存儲結(jié)構(gòu)。當(dāng)用戶輸入搜索語句后,相應(yīng)的分詞函數(shù)會對語句進行分解獲得關(guān)鍵詞,然后再根據(jù)每個關(guān)鍵詞查找到相應(yīng)的URL。通過這種結(jié)構(gòu),可以快速的獲取這個單詞所對應(yīng)的地址列表。在這里使用樹形結(jié)構(gòu)的存儲方式,Python的字典和列表類型能夠較好的構(gòu)建出單詞詞典樹。
從隊列中彈出目前的URL地址,在爬取隊列不為空的條件下,算法不斷從隊列中獲取到新的網(wǎng)頁地址,并重復(fù)上述過程。
實現(xiàn):
環(huán)境:
Python3.5orAnaconda3
BeautifulSoup4
可以使用下面的指令安裝BeautifulSoup4,如果你是Ubuntu用戶,記得在命令前面加上sudo:
pip install beautifulsoup4
程序分別實現(xiàn)了幾個類,分別用于URL地址管理,Html內(nèi)容請求、Html內(nèi)容解析、索引建立以及爬蟲主進程。我將整個程序按照每個Class分開解釋,最后只要將他們放在一起就可以執(zhí)行代碼了。
UrlManager類
這個類用來管理URL地址,new_urls用來保存還未爬取的URL地址,old_urls保存了已經(jīng)爬取過的地址,兩個變量都使用set類型保證其中內(nèi)容的唯一性。每次循環(huán)時,add_new_urls()向外提供了向new_urls變量中添加新urls的方法;add_new_url()方法,對每個url地址進行重復(fù)性檢查,符合條件的才進行添加操作;get_urls()向外提供了獲取新的url地址的方法;has_new_url()方法用來檢查爬取隊列是否為空。
import re import urllib.request import urllib.parse from bs4 import BeautifulSoup class UrlManager(object): def __init__(self): self.new_urls = set() self.old_urls = set() def add_new_url(self, url): if url is None: return if url not in self.new_urls and url not in self.old_urls: self.new_urls.add(url) def add_new_urls(self, urls): if urls is None or len(urls) == 0: return for url in urls: self.add_new_url(url) def has_new_url(self): return len(self.new_urls) != 0 def get_new_url(self): new_url = self.new_urls.pop() self.old_urls.add(new_url) return new_url
HtmlDownloader類
這個類實現(xiàn)了向url地址發(fā)送Request請求,并獲取其回應(yīng)的方法,調(diào)用類內(nèi)的download()方法就可實現(xiàn)。這里要注意的是頁面的編碼問題,這里我使用的是UTF-8來進行decode解碼,有的網(wǎng)頁可能使用的是GBK編碼,要根據(jù)實際情況進行修改。
class HtmlDownloader(object): def download(self, url): if url is None: return None try: request = urllib.request.Request(url) response = urllib.request.urlopen(request) content = response.read().decode('utf-8').encode('utf-8') if content is None: return None if response.getcode() != 200: return None except urllib.request.URLError as e: print(e) return None return content
HtmlParser類
這個類通過實例化一個BeautifulSoup對象來進行頁面的解析。它是一個使用Python編寫的HTML/XML文檔解析器。它通過將文檔解析為DOM樹的方式為用戶提供需要抓取的數(shù)據(jù),并且提供一些簡單的函數(shù)用來處理導(dǎo)航、搜索、修改分析樹等功能。
該類的關(guān)鍵是_get_new_urls()、_get_new_content()、get_url_title()三個方法。第一個方法用來解析出頁面包含的超鏈接,最為重要的選擇要解析的標(biāo)簽并為其構(gòu)造合適的正則表達式。這里我為a標(biāo)簽定義了一個匹配正則,用來獲取所有的站內(nèi)鏈接,如下:
links = soup.find_all('a', href=re.compile(r'^(%s).*(/|html)$' % self.domain))`
后面的兩個類都是通過解析Html標(biāo)簽來獲取title的方法,最終在parse()中通過調(diào)取_get_new_content()來獲得title內(nèi)容。具體的標(biāo)簽訪問方法不細談了,讀者可以自己翻閱BeautifulSoup的官方文檔。
class HtmlParser(object): def __init__(self, domain_url): self.domain = domain_url self.res = HtmlDownloader() def _get_new_urls(self, page_url, soup): new_urls = set() links = soup.find_all('a', href=re.compile(r'^(%s).*(/|html)$' % self.domain)) try: for link in links: new_url = link['href'] new_full_url = urllib.parse.urljoin(self.domain, new_url) new_urls.add(new_full_url) new_urls = list(new_urls) return new_urls except AttributeError as e: print(e) return None def _get_new_content(self, page_url, soup): try: title_name = soup.title.string return title_name except AttributeError as e: print(e) return None def get_url_title(self): content = self.res.download(self.domain) try: soup = BeautifulSoup(content, 'html.parser', from_encoding='utf-8') title_name = soup.title.string return title_name except: title_name = 'None Title' return title_name def parse(self, page_url, html_cont): if page_url is None or html_cont is None: return None soup = BeautifulSoup(html_cont, 'html.parser', from_encoding='utf-8') new_data = self._get_new_content(page_url, soup) new_urls = self._get_new_urls(page_url, soup) return new_urls, new_data
BuildIndex
該類為每個URL地址與他的標(biāo)題包含的關(guān)鍵詞建立了一個索引關(guān)系并保存在一個Dict變量中,每個標(biāo)題對應(yīng)多個關(guān)鍵詞,每個標(biāo)題也對應(yīng)多個url地址,因此每個關(guān)鍵詞也對應(yīng)了多個url地址,具體的形式如下:
index={'keyword':[url1,url2,...,urln],...}
其中,add_page_index()方法對每個標(biāo)題進行了分詞處理,并且調(diào)用了add_key_index()方法將keyword-url的對應(yīng)關(guān)系存到索引中,這其中也進行了重復(fù)檢查。主意,這個分詞方法僅限于英文句子,中文的話需要用到特定的分詞工具。
class BuildIndex(object): def add_page_index(self, index, url, content): words = content.split() for word in words: index = self.add_key_index(index, url, word) return index def add_key_index(self, index, url, keyword): if keyword in index: if url not in index[keyword]: index[keyword].append(url) else: temp = [] index[keyword] = temp index[keyword].append(url) return index
SpiderMain
這是爬蟲的主題類,它通過調(diào)用其他幾個類生成的對象來實現(xiàn)爬蟲的運行。該類實例化的時候會永久生成上面幾個類的對象,當(dāng)通過craw()方法獲取到用戶提供的url地址時,就會依次進行請求、下載、解析、建立索引的工作。最后該方法會返回index,graph兩個變量,他們分別是:
每個關(guān)鍵詞集齊對應(yīng)的地址,keyword-urls索引,如下
index={'keyword':[url1,url2,...,urln],...}
每個url及其頁面中包含的urls,url-suburls索引,如下
graph={'url':[url1,url2,...,urln],...}
class SpiderMain(object): def __init__(self, root_url): self.root_url = root_url self.urls = UrlManager() self.downloader = HtmlDownloader() self.parser = HtmlParser(self.root_url) self.build = BuildIndex() def craw(self): index = graph = {} self.urls.add_new_url(self.root_url) while self.urls.has_new_url(): try: new_url = self.urls.get_new_url() html_cont = self.downloader.download(new_url) new_urls, new_title = self.parser.parse(new_url, html_cont) index = self.build.add_page_index(index, new_url, new_title) graph[new_url] = list(new_urls) self.urls.add_new_urls(new_urls) except Exception as e: print(e) return None return index, graph
最后,我們在程序中添加下面的代碼,就可以成功的執(zhí)行我們的爬蟲了
if __name__ == '__main__': spider = SpiderMain('http://www.xael.org/') index, graph = spider.craw() print(index) print(graph)
以上是“Python怎么實現(xiàn)簡易Web爬蟲”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計公司行業(yè)資訊頻道!
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。