欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python實(shí)現(xiàn)簡易Web爬蟲詳解

 更新時間:2018年01月03日 09:15:49   作者:洛荷  
這篇文章主要介紹了Python實(shí)現(xiàn)簡易Web爬蟲詳解,具有一定借鑒價值,需要的朋友可以參考下

簡介:

網(wǎng)絡(luò)爬蟲(又被稱為網(wǎng)頁蜘蛛),網(wǎng)絡(luò)機(jī)器人,是一種按照一定的規(guī)則,自動地抓信息的程序或者腳本。假設(shè)互聯(lián)網(wǎng)是一張很大的蜘蛛網(wǎng),每個頁面之間都通過超鏈接這根線相互連接,那么我們的爬蟲小程序就能夠通過這些線不斷的搜尋到新的網(wǎng)頁。

Python作為一種代表簡單主義思想的解釋型、面向?qū)ο?、功能?qiáng)大的高級編程語言。它語法簡潔并且具有動態(tài)數(shù)據(jù)類型和高層次的抽象數(shù)據(jù)結(jié)構(gòu),這使得它具有良好的跨平臺特性,特別適用于爬蟲等程序的實(shí)現(xiàn),此外Python還提供了例如Spyder這樣的爬蟲框架,BeautifulSoup這樣的解析框架,能夠輕松的開發(fā)出各種復(fù)雜的爬蟲程序。

在這篇文章中,使用Python自帶的urllib和BeautifulSoup庫實(shí)現(xiàn)了一個簡單的web爬蟲,用來爬取每個URL地址及其對應(yīng)的標(biāo)題內(nèi)容。

流程:

爬蟲算法從輸入中讀取的一個URL作為初始地址,向該地址發(fā)出一個Request請求。

請求的地址返回一個包含所有內(nèi)容的,將其存入一個String變量,使用該變量實(shí)例化一個BeautifulSoup對象,該對象能夠?qū)?nèi)容并且將其解析為一個DOM樹。

根據(jù)自己的需要建立正則表達(dá)式,最后借助HTML標(biāo)簽從中解析出需要的內(nèi)容和新的URL,將新的放入隊(duì)列中。

對于目前所處的URL地址與爬去的內(nèi)容,在進(jìn)行一定的過濾、整理后會建立索引,這是一個單詞-頁面的存儲結(jié)構(gòu)。當(dāng)用戶輸入搜索語句后,相應(yīng)的分詞函數(shù)會對語句進(jìn)行分解獲得關(guān)鍵詞,然后再根據(jù)每個關(guān)鍵詞查找到相應(yīng)的URL。通過這種結(jié)構(gòu),可以快速的獲取這個單詞所對應(yīng)的地址列表。在這里使用樹形結(jié)構(gòu)的存儲方式,Python的字典和列表類型能夠較好的構(gòu)建出單詞詞典樹。

從隊(duì)列中彈出目前的URL地址,在爬取隊(duì)列不為空的條件下,算法不斷從隊(duì)列中獲取到新的網(wǎng)頁地址,并重復(fù)上述過程。

實(shí)現(xiàn):

環(huán)境:

Python3.5orAnaconda3

BeautifulSoup4

可以使用下面的指令安裝BeautifulSoup4,如果你是Ubuntu用戶,記得在命令前面加上sudo:

pip install beautifulsoup4

程序分別實(shí)現(xiàn)了幾個類,分別用于URL地址管理,Html內(nèi)容請求、Html內(nèi)容解析、索引建立以及爬蟲主進(jìn)程。我將整個程序按照每個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地址進(jìn)行重復(fù)性檢查,符合條件的才進(jìn)行添加操作;get_urls()向外提供了獲取新的url地址的方法;has_new_url()方法用來檢查爬取隊(duì)列是否為空。

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類

這個類實(shí)現(xiàn)了向url地址發(fā)送Request請求,并獲取其回應(yīng)的方法,調(diào)用類內(nèi)的download()方法就可實(shí)現(xiàn)。這里要注意的是頁面的編碼問題,這里我使用的是UTF-8來進(jìn)行decode解碼,有的網(wǎng)頁可能使用的是GBK編碼,要根據(jù)實(shí)際情況進(jìn)行修改。

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類

這個類通過實(shí)例化一個BeautifulSoup對象來進(jìn)行頁面的解析。它是一個使用Python編寫的HTML/XML文檔解析器。它通過將文檔解析為DOM樹的方式為用戶提供需要抓取的數(shù)據(jù),并且提供一些簡單的函數(shù)用來處理導(dǎo)航、搜索、修改分析樹等功能。

該類的關(guān)鍵是_get_new_urls()、_get_new_content()、get_url_title()三個方法。第一個方法用來解析出頁面包含的超鏈接,最為重要的選擇要解析的標(biāo)簽并為其構(gòu)造合適的正則表達(dá)式。這里我為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)簽訪問方法不細(xì)談了,讀者可以自己翻閱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)題進(jìn)行了分詞處理,并且調(diào)用了add_key_index()方法將keyword-url的對應(yīng)關(guān)系存到索引中,這其中也進(jì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)用其他幾個類生成的對象來實(shí)現(xiàn)爬蟲的運(yùn)行。該類實(shí)例化的時候會永久生成上面幾個類的對象,當(dāng)通過craw()方法獲取到用戶提供的url地址時,就會依次進(jìn)行請求、下載、解析、建立索引的工作。最后該方法會返回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)

總結(jié)

以上就是本文關(guān)于Python實(shí)現(xiàn)簡易Web爬蟲詳解的全部內(nèi)容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!

相關(guān)文章

  • Python 實(shí)現(xiàn)刪除某路徑下文件及文件夾的實(shí)例講解

    Python 實(shí)現(xiàn)刪除某路徑下文件及文件夾的實(shí)例講解

    下面小編就為大家分享一篇Python 實(shí)現(xiàn)刪除某路徑下文件及文件夾的實(shí)例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • python中字典的常見操作總結(jié)1

    python中字典的常見操作總結(jié)1

    這篇文章主要介紹了python中字典的常見操作總結(jié),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-07-07
  • Appium+python+unittest搭建UI自動化框架的實(shí)現(xiàn)

    Appium+python+unittest搭建UI自動化框架的實(shí)現(xiàn)

    本文主要介紹了Appium+python+unittest搭建UI自動化框架的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-03-03
  • Python中win32com模塊的使用

    Python中win32com模塊的使用

    本文主要介紹了Python中win32com模塊的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • python實(shí)現(xiàn)PID算法及測試的例子

    python實(shí)現(xiàn)PID算法及測試的例子

    今天小編就為大家分享一篇python實(shí)現(xiàn)PID算法及測試的例子,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-08-08
  • Python3爬蟲學(xué)習(xí)之MySQL數(shù)據(jù)庫存儲爬取的信息詳解

    Python3爬蟲學(xué)習(xí)之MySQL數(shù)據(jù)庫存儲爬取的信息詳解

    這篇文章主要介紹了Python3爬蟲學(xué)習(xí)之MySQL數(shù)據(jù)庫存儲爬取的信息,涉及Python3針對mysql數(shù)據(jù)庫的連接、信息存儲等相關(guān)操作技巧,需要的朋友可以參考下
    2018-12-12
  • Python的Tornado框架實(shí)現(xiàn)圖片上傳及圖片大小修改功能

    Python的Tornado框架實(shí)現(xiàn)圖片上傳及圖片大小修改功能

    Tornado是一個異步的Python Web開發(fā)框架,同時也是一個優(yōu)秀的異步服務(wù)器開發(fā)庫,這里我們將來講解一下Python的Tornado框架實(shí)現(xiàn)圖片上傳及圖片大小修改功能方面的一些重點(diǎn):
    2016-06-06
  • keras獲得某一層或者某層權(quán)重的輸出實(shí)例

    keras獲得某一層或者某層權(quán)重的輸出實(shí)例

    今天小編就為大家分享一篇keras獲得某一層或者某層權(quán)重的輸出實(shí)例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-01-01
  • 基于python實(shí)現(xiàn)復(fù)制文件并重命名

    基于python實(shí)現(xiàn)復(fù)制文件并重命名

    這篇文章主要介紹了基于python實(shí)現(xiàn)復(fù)制文件并重命名,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-09-09
  • Python中g(shù)lobal關(guān)鍵字的用法詳解

    Python中g(shù)lobal關(guān)鍵字的用法詳解

    Python是一種簡單而強(qiáng)大的編程語言,提供了許多功能和語法來幫助開發(fā)人員編寫高效的代碼,其中一個常用的功能是使用global關(guān)鍵字來在函數(shù)內(nèi)部訪問和修改全局變量,在本文中,我們將深入探討Python中g(shù)lobal關(guān)鍵字的用法,以及使用它的一些最佳實(shí)踐
    2023-12-12

最新評論