衡阳派盒市场营销有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

爬蟲的基本工作原理 用Scrapy實現一個簡單的爬蟲

CHANBAEK ? 來源:郎哥編程課堂 ? 作者:郎宏林 ? 2023-12-03 11:45 ? 次閱讀

數以萬億的網頁通過鏈接構成了互聯網,爬蟲的工作就是從這數以萬億的網頁中爬取需要的網頁,從網頁中采集內容并形成結構化的數據。

1、 爬蟲的基本工作原理

爬蟲是就是一個程序,這個程序的任務就是從給出的一組種子URL開始爬取網頁,并通過網頁間的鏈接爬取更多的網頁,根據爬蟲任務的需求,最終可能會爬取整個互聯網的網頁。

爬蟲的工作機制如下圖示:

圖片

URL就是網頁的網址,種子URL就是爬蟲要首先爬取的網頁網址,確定你的爬蟲程序首先從哪些網頁開始爬取。一組種子URL是指一個或多個的網頁地址。

爬蟲程序開始工作后,種子URL會先加入到待爬取網頁的隊列中,爬蟲程序從隊列按照先進先出的原則獲取網頁URL,爬蟲程序開始爬取網頁,爬蟲會下載整個網頁內容,然后提取網頁內容,分析出網頁內容包含的URL,并把新的URL加入到隊列。

當隊列為空時,爬蟲停止工作,否則爬蟲會繼續從隊列獲取網頁URL,爬取下一個網頁。

Python爬蟲基礎代碼如下:

# 導入隊列模塊
import queue as q
# 定義種子URL
seed_url = ["https://news.baidu.com/","https://money.163.com/"]
# 定義URL隊列
url_queue = q.Queue()
# 定義添加種子到隊列的函數
def put_seed():
    for s in seed_url:
        url_queue.put(s)
# 定義網址添加到隊列的函數
def put_url(url):
    url_queue.put(url)
# 定義判斷隊列是否不為空函數
def is_queue_noempty():
    if url_queue.empty():
        return False
    return True
    
# 定義從隊列獲取URL的函數
def get_url():
    return url_queue.get()
# 定義網頁下載函數
def download_url(url):
    text = "";
    # 此處為下載代碼
    pass
    return text
# 定義網頁解析函數
def analysis(text):
    # 此處為網頁內容解析代碼
    pass
    # 網頁內容處理與存儲代碼
    process()
    # 添加新URL到隊列
    pass
# 定義網頁內容處理與存儲函數
def process(objec=None):
    # 此處為網頁內容處理與存儲代碼
    pass
  
if __name__ == "__main__":
    
    print("------啟動爬蟲------")
    # 種子URL加入隊列
    put_seed()
    # 循環爬取隊列的URL
    while is_queue_noempty():
        # 從隊列獲取URL
        url = get_url()
        # 下載URL
        text = download_url(url)
        # 解析網頁內容
        analysis(text)
        
    # 隊列為空,爬蟲停止
    print("------爬蟲停止------")

用Scrapy實現一個簡單的爬蟲

Scrapy是一個為了爬取網站數據,提取結構性數據而編寫的應用框架。應用框架提供了很多工具和程序,讓我們可以輕松開發商業化爬蟲,商業化爬蟲是指實用的爬蟲程序。

下面用Scrapy實現一個簡單的爬蟲。

(1)創建爬蟲項目

使用Scrapy實現爬蟲,需要創建一個新的Scrapy項目。創建一個Scrapy項目非常簡單,使用Scrapy命令行工具就可以創建Scrapy項目,Scrapy命令行工具可以運行在Windows的命令行窗口或Linux的終端窗口。

運行命令行工具的語法如下:

scrapy < command > [options] [args]

其中,scrapy是工具名稱,command是命令,options是命令的選項,args是命令需要的參數,options和args是可選的,依據命令的要求傳入。

下面介紹三個主要的命令,創建項目命令、爬蟲創建命令和運行項目爬蟲命令,因為這三個命令是馬上要用到的。其它命令會專門安排一個小節介紹。

創建項目命令

創建項目的語法如下:

scrapy startproject < project_name >

其中startproject是創建項目的命令名稱,project_name是項目名稱。例如:要創建一個爬取百度新聞網站數據的爬蟲,項目名稱可以是newsbaidu。

創建newsbaidu項目的命令如下:

scrapy startproject newsbaidu

爬蟲創建命令

爬蟲創建命令用于在項目中創建一個爬蟲,爬蟲的英文名稱spider。這是創建spider的一種快捷方法,該命令可以使用提前定義好的模板來生成spider,也可以自己創建spider的源碼文件。

爬蟲創建命令的語法如下:

scrapy genspider [-t template] < name > < domain >

其中genspider是爬蟲創建命令的命令名稱,template用來設置爬蟲源代碼的模板名稱,這是一個可選項,采用scrapy的默認爬蟲模板即可,name是爬蟲名稱,domain是該爬蟲要爬取的網站域名。

運行項目爬蟲命令

一個scrapy項目可以運行多個爬蟲,運行項目爬蟲命令的語法如下:

scrapy crawl < spider >

其中crawl是運行項目爬蟲命令的名稱,spider是爬蟲名稱,也就是使用爬蟲創建命令創建的爬蟲名稱。

創建爬蟲項目及爬蟲

在Windows命令行窗口,將存儲項目文件的目錄設置為當前目錄,使用scrapy工具的startproject命令創建爬蟲項目newsbaidu,項目名稱也可以是其它名稱,在Windows命令行窗口輸入下面的命令:

scrapy startproject newsbaidu

在項目中創建爬蟲spider_newsbaidu,設置項目所在目錄為當前工作目錄,在Windows命令行窗口輸入下面的命令:

scrapy genspider spider_newsbaidu https://news.baidu.com

(2)定義要抓取的數據

開發爬蟲的目的是要爬取網站數據,并提取出結構化數據。要做的第一步工作就是根據要爬取的網站內容構成,定義一個結構化數據,存儲從網站提取的數據。

在scrapy中,通過scrapy Items來完成結構化數據的定義。在scrapy創建的爬蟲項目中,items.py文件就是一個Items,在Items可以定義要爬取的數據。

例如:要抓取百度新聞網站(news.baidu.com)的熱點新聞條目,并獲取新聞條目的文章標題、文章鏈接數據。

可以在項目的items.py文件中定義下面的數據結構:

# 導入scrapy庫
import scrapy
#自定義NewsbaiduItem用于存儲爬蟲所抓取的字段內容
class NewsbaiduItem(scrapy.Item):
    # 定義要爬取的數據:
    # 文章標題
    news_title = scrapy.Field()
    # 文章鏈接
    news_link = scrapy.Field()

NewsbaiduItem類繼承scrapy.Item類,它是一個Scrapy Items,它定義了兩個數據字段,分別是news_title和news_link。

類似這樣的Scrapy Items可以定義多個,以適應爬取不同的網站數據。

(3)編寫一個爬蟲程序

定義了存儲爬取數據的Scrapy Items,就可以開始編寫爬蟲程序了。首先要確定百度新聞網站的起始頁,也就是百度新聞網站的種子URL。

爬蟲的種子URL:www.news.baidu.com

種子URL是百度新聞網站的首頁,需要查看百度新聞網站的首頁源碼,確定提取新聞條目的規則,編寫XPath表達式。

如何查看網頁源碼?

使用瀏覽器打開百度新聞網站的首頁,單擊鼠標右鍵,在彈出的菜單中選擇“查看網頁源代碼”命令,不同瀏覽器可能有不同的命令名稱。

觀察網頁源代碼,找出數據提取規則

觀察首頁源代碼發現,新聞條目的源代碼一般都通過下面的超鏈接標簽實現:

< a href="https://3w.huanqiu.com/a/9eda3d/3zT0a2ZsWaC?agt=8" 
mon="ct=1&a=2&c=top&pn=15" 
target="_blank" >
英國將法國荷蘭列入隔離清單,法國:將采取“對等措施”
< /a >

其中,“a”是超鏈接標簽,也稱為a標簽。“href”是超鏈接的目標屬性,“mon”應是百度新聞網站自定義的一個超鏈接屬性,每個新聞條目的a標簽都帶有mon屬性,通過a標簽的mon屬性可以和網頁的其它a標簽區分開。

提取新聞條目的XPath表達式如下:

//a[contains(@mon,'ct=1')]

a標簽的mon屬性值的“&”是轉義符,表示這是一個“&”字符,在XPath表達式中只有判斷mon屬性值包含字符串“ct=1”就可以提取網頁所有的新聞條目。

編寫爬蟲代碼

項目spiders目錄下的spider_newsbaidu.py是scrapy創建的一個爬蟲模板文件,可以在此基礎上修改代碼。

模板文件代碼如下:

import scrapy
class SpiderNewsbaiduSpider(scrapy.Spider):
    name = 'spider_newsbaidu'
    allowed_domains = ['https://news.baidu.com']
    start_urls = ['https://news.baidu.com/']
    def parse(self, response):
        pass

SpiderNewsbaiduSpider類繼承scrapy.Spider類。屬性name是爬蟲名稱,該名稱可用于運行項目爬蟲的crawl命令;屬性allowed_domains是要爬取的網站域名,start_urls是種子URL,start_urls是一個列表對象,可以定義多個種子URL。

在SpiderNewsbaiduSpider類可以編寫爬取網站的代碼,從下載的網頁代碼中提取超鏈接,加入爬取隊列,以及從網頁的內容中提取結構化數據。

類方法parse(response)用于解析網頁內容,提取網頁的超鏈接和結構化數據。該方法是一個回調函數,會被Request對象調用,Request對象是向網頁發出請求訪問的對象,該對象會返回一個response對象,并調用parse(response)方法對response對象進行處理。

傳入的參數是response對象,response對象封裝了爬蟲從網站爬取的內容,通過response對象可以獲取爬取的網頁內容。

修改后的爬蟲代碼如下:

import scrapy
# 導入scrapy選擇器
from scrapy.selector import Selector
# 導入NewsbaiduItem
from newsbaidu.items import NewsbaiduItem
class SpiderNewsbaiduSpider(scrapy.Spider):
    name = 'spider_newsbaidu'
    allowed_domains = ['https://news.baidu.com']
    start_urls = ['https://news.baidu.com/']
    def parse(self, response):
        # 獲取爬取下來的網頁內容
        html = response.text
        # 使用xpath表達式搜尋指定的a標簽節點,節點以列表方式返回
        item_nodes = response.xpath("http://a[contains(@mon,'ct=1')]").extract()
        # 遍歷節點
        for item_node in item_nodes:
            # 使用xpath表達式獲取節點的href屬性值
            a_href = Selector(text=str(item_node)).xpath('//@href').extract()
            # 使用xpath表達式獲取節點的文本內容
            a_text = Selector(text=str(item_node)).xpath('//text()').extract()
            # 實例化NewsbaiduItem對象
            item = NewsbaiduItem()
            item["news_title"] = a_text
            item["news_link"] = a_href
            # 使用yield語句返回item給parse的調用者
            yield item

主要修改了parse()方法,在parse()方法內,通過response對象的text屬性獲取scrapy下載的網頁內容,通過response對象的xpath()方法執行XPath表達式選取網頁節點或節點文本,將提取的網頁數據存儲到NewsbaiduItem對象。

parse()方法使用了yield語句,因此parse()方法是一個生成器函數,當parse()方法的調用者需要一個迭代對象時,parse()方法會返回這個迭代對象。

parse()方法返回的迭代對象主要是兩類:一類是scrapy Items類型的實例對象;一類是scrapy Request類型的實例對象,Request對象封裝了請求的URL。

(4)運行爬蟲

當前創建的SpiderNewsbaiduSpider爬蟲還是非常簡單的,在爬蟲內并沒有處理網頁內新聞條目外的超鏈接,因此爬蟲處理完該網頁內容后,就會自行結束爬取過程。隨著對scrapy框架的深入了解,會逐漸完善SpiderNewsbaiduSpider爬蟲。

現在可以運行爬蟲了,爬取的數據暫時存儲到json文件,在后面的課程會存儲到數據庫。

在Windows命令行窗口,將當前目錄切換到項目的根目錄,輸入下面的命令:

scrapy crawl spider_newsbaidu -o items.json

其中spider_newsbaidu是爬蟲名稱,選項-o是將Items輸出到文件,選項-o后面的參數是文件名稱。

執行運行爬蟲的命令后,爬蟲爬取的數據會存儲到項目根目錄下的items.json文件,可以使用記事本查看items.json文件內容。

若items.json文件的中文內容顯示為文字編碼,需要在setting.py文件中添加FEED_EXPORT_ENCODING配置項,該配置項用于設置輸出文件的字符編碼方式,scrapy輸出文件的默認字符編碼是ASCII。

通過在setting.py文件添加下面的配置項將scrapy輸出文件字符編碼設置為utf-8。

FEED_EXPORT_ENCODING = 'utf-8'

** Scrapy爬蟲的工作機制**

基于當前學到的scrapy知識,整理出scrapy的工作機制,在后面的課程會逐步完善scrapy的工作機制。

圖片

Scrapy引擎是Scrapy框架的核心,它可以啟動多個爬蟲,并管理爬蟲的運行。

它會將爬蟲提取的Request對象放入到Scrapy調度器(可以把Scrapy調度器看作是URL隊列管理),同時它會調用Items數據處理器處理爬蟲提取的Items數據。

Scrapy引擎會維持爬蟲的運行,維持爬蟲運行的機制就是不斷從URL隊列管理器獲取Request對象,調用下載管理器向Request對象指定的URL發出Request請求,下載URL所在服務器返回的內容,并返回Responses對象。

Request對象會回調在Request對象設置的回調函數,并傳入Responses對象。若Request對象沒有設置回調函數,將會調用Spider的parse()方法。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 互聯網
    +關注

    關注

    54

    文章

    11185

    瀏覽量

    103863
  • 代碼
    +關注

    關注

    30

    文章

    4825

    瀏覽量

    69044
  • python
    +關注

    關注

    56

    文章

    4807

    瀏覽量

    85037
  • 爬蟲
    +關注

    關注

    0

    文章

    82

    瀏覽量

    7006
收藏 人收藏

    評論

    相關推薦

    Python數據爬蟲學習內容

    流程來實現的。這個過程其實就是模擬了一個人工瀏覽網頁的過程。Python中爬蟲相關的包很多:urllib、requests、bs4、scrapy、pyspider 等,我們可以按照re
    發表于 05-09 17:25

    Python爬蟲與Web開發庫盤點

    的接口,般我們都是和正則結合使用,如果對速度有要求的話,建議lmxp,它比bs4 速度要快很多。2.Scrapy爬蟲的世界里面有沒有懶人專用的框架,當然有啦,
    發表于 05-10 15:21

    Python爬蟲初學者需要準備什么?

    ,想從事這方面的工作,需掌握以下知識:1. 學習Python基礎知識并實現基本的爬蟲過程般獲取數據的過程都是按照發送請求-獲得頁面反饋-解析并且存儲數據 這三
    發表于 06-20 17:14

    爬蟲框架scrapy包括了以下組件

    爬蟲框架scrapy
    發表于 04-03 15:57

    Scrapy爬蟲架構流程圖詳解

    Scrapy爬蟲框架
    發表于 09-25 14:15

    什么語言適合寫爬蟲

    和框架實際上也要花費不少時間。比如我接觸的 Scrapy,配環境就配了兩天,對于里面復雜的結構更是云里霧里,任何爬蟲都可以只使用幾個簡單的庫來實現,雖然耗費了很多時間,但是對整個 HT
    發表于 01-14 13:51

    什么語言適合寫爬蟲

    和框架實際上也要花費不少時間。比如我接觸的 Scrapy,配環境就配了兩天,對于里面復雜的結構更是云里霧里,任何爬蟲都可以只使用幾個簡單的庫來實現,雖然耗費了很多時間,但是對整個 HT
    發表于 02-03 13:22

    使用scrapy-Redis的爬蟲項目

    scrapy-Redis分布式爬蟲
    發表于 03-24 10:24

    Ubuntu 1604后臺如何運行scrapy爬蟲程序

    Ubuntu 1604后臺運行scrapy爬蟲程序
    發表于 05-25 12:32

    如何通過網頁開啟scrapy爬蟲

    通過網頁開啟scrapy爬蟲,scrapydganjo結合
    發表于 06-05 15:56

    Python爬蟲速成指南讓你快速的學會寫簡單爬蟲

    本文主要內容:以最短的時間寫簡單爬蟲,可以抓取論壇的帖子標題和帖子內容。 本文受眾:沒寫過爬蟲的萌新。
    的頭像 發表于 06-10 09:57 ?7130次閱讀
    Python<b class='flag-5'>爬蟲</b>速成指南讓你快速的學會寫<b class='flag-5'>一</b><b class='flag-5'>個</b>最<b class='flag-5'>簡單</b>的<b class='flag-5'>爬蟲</b>

    爬蟲是如何實現數據的獲取爬蟲程序如何實現

    進入大數據時代,爬蟲技術越來越重要,因為它是獲取數據的重要手段,是大數據和云計算的基礎。那么,爬蟲到底是如何實現數據的獲取的呢?今天和大
    發表于 01-02 16:30 ?10次下載
    <b class='flag-5'>爬蟲</b>是如何<b class='flag-5'>實現</b>數據的獲取<b class='flag-5'>爬蟲</b>程序如何<b class='flag-5'>實現</b>

    如何理解爬蟲工程師

    我之前寫了很多關于爬蟲的文章,涉及了各種各樣的爬取策略;也爬了不少主流非主流的網站。從我剛入門爬蟲到現在,每一個爬蟲對應的文章都可以在我的博客上找到,不論是最最
    的頭像 發表于 09-18 11:39 ?2969次閱讀

    python實現簡單爬蟲的資料說明

    本文檔的主要內容詳細介紹的是python實現簡單爬蟲的資料說明。
    發表于 11-02 17:53 ?21次下載
    python<b class='flag-5'>實現</b><b class='flag-5'>簡單</b><b class='flag-5'>爬蟲</b>的資料說明

    feapder:款功能強大的爬蟲框架

    今天推薦款更加簡單、輕量級,且功能強大的爬蟲框架:feapder 項目地址: https://github.com/Boris-code/feapder 2. 介紹及安裝 和 Scrapy
    的頭像 發表于 11-01 09:48 ?1140次閱讀
    中华百家乐官网娱乐城| 百家乐官网搏牌| 澳博娱乐| 百家乐官网视频游戏挖坑| 百家乐官网博彩平| 百家乐平台哪个好本站所有数据都是网友推荐及提供 | 百家乐赢赌场百家乐| 百家乐麻将筹码币| 伟博娱乐| 百家乐官网路单统| 在线百家乐作| 百家乐官网实战技术| 百家乐官网发牌靴8| 百家乐代理合作| 百家乐官网游戏奥秘| LV百家乐官网客户端LV| 百家乐鞋| 联众棋牌游戏大厅| 百家乐官网一般的庄闲比例是多少| 网上百家乐是叫九五至尊么| 任你博| 沛县| 百家乐下注所有组合| 大发888游戏是真的么| 澳门百家乐官网哪家信誉最好 | 百家乐游戏开发技术| 娱乐城开户送现金| 百家乐官网赌场代理合作| 百家乐怎样玩的| 金冠百家乐官网娱乐城| 百家乐投注庄闲法| 金冠娱乐城官网| 网页百家乐游戏| 蒙特卡罗娱乐场| 百家乐视频交友| 肯博娱乐| 百家乐试玩账户| 澳门新葡京赌场| 澳门百家乐玩大小| 百家乐网上娱乐| CEO百家乐现金网|