python通過連結抓取網站詳解
在本篇文章裡,你將會學習把這些基本方法融合到一個更靈活的網站 爬蟲中,該爬蟲可以跟蹤任意遵循特定 URL 模式的連結。
這種爬蟲非常適用於從一個網站抓取所有資料的專案,而不適用於從特 定搜尋結果或頁面列表抓取資料的專案。它還非常適用於網站頁面組織 得很糟糕或者非常分散的情況。
這些型別的爬蟲並不需要像上一節通過搜尋頁面進行抓取中採用的定位 連結的結構化方法,因此在 Website 物件中不需要包含描述搜尋頁面 的屬性。但是由於爬蟲並不知道待尋找的連結的位置,所以你需要一些 規則來告訴它選擇哪種頁面。你可以用 targetPattern(目標 URL 的 正則表示式)和布林變數 absoluteUrl 來達成這一目標:
class Website: def __init__(self,name,url,targetPattern,absoluteUrl,titleTag,bodyTag): self.name = name self.url = url self.targetPattern = targetPattern self.absoluteUrl=absoluteUrl self.titleTag = titleTag self.bodyTag = bodyTag class Content: def __init__(self,title,body): self.url = url self.title = title self.body = body def print(self): print("URL: {}".format(self.url)) print("TITLE: {}".format(self.title)) print("BODY:\n{}".format(self.body))
Content 類和第一個爬蟲例子中使用的是一樣的。
Crawler 類從每個網站的主頁開始,定位內鏈,並解析在每個內鏈頁面 發現的內容:
import re class Crawler: def __init__(self,site): self.site = site self.visited = [] def getPage(self,url): try: req = requests.get(url) except requests.exceptions.RequestException: return None return BeautifulSoup(req.text,'html.parser') def safeGet(self,pageObj,selector): selectedElems = pageObj.select(selector) if selectedElems is not None and len(selectedElems) > 0: return '\n'.join([elem.get_text() for elem in selectedElems]) return '' def parse(self,url): bs = self.getPage(url) if bs is not None: title = self.safeGet(bs,self.site.titleTag) body = self.safeGet(bs,self.site.bodyTag) if title != '' and body != '': content = Content(url,body) content.print() def crawl(self): """ 獲取網站主頁的頁面連結 """ bs = self.getPage(self.site.url) targetPages = bs.findAll('a',href=re.compile(self.site.targetPattern)) for targetPage in targetPages: targetPage = targetPage.attrs['href'] if targetPage not in self.visited: self.visited.append(targetPage) if not self.site.absoluteUrl: targetPage = '{}{}'.format(self.site.url,targetPage) self.parse(targetPage) reuters = Website('Reuters','https://www.reuters.com','^(/article/)',False,'h1','div.StandardArticleBody_body_1gnLA') crawler = Crawler(reuters) crawler.crawl()
與前面的例子相比,這裡的另外一個變化是:Website 物件(在這個例 子中是變數 reuters)是 Crawler 物件本身的一個屬性。這樣做的作 用是將已訪問過的頁面儲存在爬蟲中,但是也意味著必須針對每個網站 例項化一個新的爬蟲,而不是重用一個爬蟲去抓取網站列表。
不管你是選擇一個與網站無關的爬蟲,還是將網站作為爬蟲的一個屬 性,這都是一個需要根據自身需求進行權衡的決定。兩種方法在功能實 現上都是沒有問題的。
另外需要注意的是,這個爬蟲會從主頁開始抓取,但是在所有頁面都被 記錄後,就不會繼續抓取了。你可能希望編寫一個爬蟲,將第 3 章中介 紹的某種模式融合進來,然後檢視所訪問的每個頁面中更多的目標 URL。你甚至還可以跟蹤每個頁面中涉及的所有 URL(不僅僅是匹配 目標模式的 URL),然後檢視這些 URL 是否包含目標模式。
以上就是關於python抓取網站的相關知識點內容,感謝大家的學習和對我們的支援。