<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] 中文文檔:http://shouce.jb51.net/scrapy0.24/topics/signals.html ## 1. 基礎概念 編寫一個爬蟲程序,大概需要以下幾步: 1. 編寫Spider類:包含要處理的url和數據解析 2. 編寫item類 : 處理解析后數據的結構化映射 3. 編寫pipeline:限定數據的去處(需要在settings配置文件導入我們寫的pipeline類) ### 1.1 scrapy架構 > * scrapy純Python實現的爬蟲框架,只需要些網頁的分析某塊,就可以實現網站數據的抓取 > * 如果是請求,scrapy交給Downloader下載,并把數據交給爬蟲,如果是數據就交給ItemPipeline處理,依次循環 ![](https://box.kancloud.cn/8c591d54457bb033812a2b0364011e9c_700x494.png) > * Scrapy Engine(引擎): 負責Spider、ItemPipeline、Downloader、Scheduler中間的通訊,信號、數據傳遞等。 > * Scheduler(調度器): 它負責接受引擎發送過來的Request請求,并按照一定的方式進行整理排列,入隊,并調用Downloader下載。當引擎需要時,交還給引擎。 > * Downloader(下載器): 負責下載scheduler(調度器)發送的所有Requests請求,并將其獲取到的Responses交還給Scrapy Engine(引擎),由引擎交給Spider來處理,對應DownloaderMiddlewareManager類 > * Spider(爬蟲): 它負責處理所有Responses,從中分析提取數據,獲取Item字段需要的數據,并將需要跟進的URL提交給引擎,再次進入Scheduler(調度器) > * Item Pipeline(管道): 它負責處理Spider中獲取到的Item,并進行進行后期處理(詳細分析、過濾、存儲等)的地方. > * Downloader Middlewares(下載中間件): 你可以當作是一個可以自定義擴展下載功能的組件。 > * Spider Middlewares(Spider中間件): 你可以理解為是一個可以自定擴展和操作引擎和Spider中間通信的功能組件(比如進入Spider的Responses;和從Spider出去的Requests) ### 1.2 數據流向 > 1. 引擎從自定義爬蟲中獲取初始化請求(也叫種子URL); > 2. 引擎把該請求放入調度器中,同時引擎向調度器獲取一個待下載的請求(這兩部是異步執行的); > 3. 調度器返回給引擎一個待下載的請求; > 4. 引擎發送請求給下載器,中間會經過一系列下載器中間件; > 5. 這個請求通過下載器下載完成后,生成一個響應對象,返回給引擎,這中間會再次經過一系列下載器中間件; > 6. 引擎接收到下載返回的響應對象后,然后發送給爬蟲,執行自定義爬蟲邏輯,中間會經過一系列爬蟲中間件; > 7. 爬蟲執行對應的回調方法,處理這個響應,完成用戶邏輯后,會生成結果對象或新的請求對象給引擎,再次經過一系列爬蟲中間件; > 8. 引擎把爬蟲返回的結果對象交由結果處理器處理,把新的請求對象通過引擎再交給調度器; > 9. 從1開始重復執行,直到調度器中沒有新的請求處理; > ### 1.3 源碼腦圖 ![](https://box.kancloud.cn/c843f1285a2e70b2b917f90439a939d2_1842x1279.png) ## 2. 入門實例 爬取傳智播客老師的數據 ![](https://box.kancloud.cn/52279555a13b55c2b4861085f47db6ee_1161x614.png) > * 我們寫爬蟲,只要寫Spider,item,pipeline這三個部分就可以了,并發、請求下載都是有scrapy完成 ### 2.1 安裝開發環境 1. Windows 安裝方式 ~~~ # python2.x pip install Scrapy # python3.x pip3 install Scrapy ~~~ Ubuntu 需要9.10或以上版本安裝方式 ~~~ Python 2 / 3 安裝非Python的依賴 sudo apt-get install python-dev python-pip libxml2-dev libxslt1-dev zlib1g-dev libffi-dev libssl-dev 通過pip 安裝 Scrapy 框架 sudo pip install scrapy ~~~ ### 2.2 編寫爬蟲程序 以爬取傳智播客的數據為例 #### 2.2.1. 新建一個爬蟲項目 ~~~ # 任意目錄下執行 scrapy startproject mySpider ~~~ mySpider :項目名稱 ![](https://box.kancloud.cn/fd9dedebd25aeefbabb7fa3bf621e185_632x222.png) mySpider目錄下還有一個mySpider 將新建的項目導入intellij ![](https://box.kancloud.cn/f1294da71c6869b13207c8dece0e0079_384x349.png) ~~~ scrapy.cfg :項目的配置文件 mySpider/ :項目的Python模塊,將會從這里引用代碼 mySpider/items.py :項目的目標文件,爬取到的數據的映射結構 mySpider/pipelines.py :項目的管道文件,規定了爬取到的數據的去處 mySpider/settings.py :項目的設置文件 mySpider/spiders/ :存儲爬蟲代碼目錄,我們寫的代碼都在這里 ~~~ #### 2.2.2 Spider爬蟲類 * 繼承scrapy.Spider類 * 四個固定寫法 > 1. name = 'tuna' 固定寫法,爬蟲標識名,用這個名驅動爬蟲程序 > 2. allowed_domains = ['itcast.cn'] 固定寫法,限制訪問的域 > 3. start_urls = ['http://www.itcast.cn/channel/teacher.shtml#aandroid','http://www.itcast.cn/channel/teacher.shtml#ac'] 固定寫法,定義爬蟲入口url,可以寫多個標識在規定域內不同類型的數據 > 4. 重寫parse方法,解析HTML數據 ~~~ # -*- coding: utf-8 -*- import scrapy from mySpider.items import teacherItem import chardet class TunaSpider(scrapy.Spider): name = 'tuna' # 爬蟲識別名稱,唯一且不同的爬蟲有不一樣的名字 allowed_domains = ['itcast.cn'] # 限制搜索域名范圍 start_urls = ['http://www.itcast.cn/channel/teacher.shtml#aandroid','http://www.itcast.cn/channel/teacher.shtml#ac'] # 爬蟲入口url,這里爬取了傳智播客的教安卓和C++的老師的數據 # 解析方法,每個初始URL完成下載后被調用,調用時傳入每個URL的傳回的 # response對象作為唯一的參數 def parse(self, response): teacher_list = response.xpath('//div[@class="li_txt"]') for each in teacher_list: item = teacherItem() # item映射 # 不加extract() 結果為xpath匹配對象 # 這里只匹配到一行文本,如果多行用extract()[0]只取一行信息導致不全 # 所有extract()獲取整個列表,再用"".join(extract())把列表轉成字符串 name = each.xpath('./h3/text()').extract()[0] # title level = each.xpath('./h4/text()').extract()[0] # info info = each.xpath('./p/text()').extract()[0] print(name[0]) # 返回的是數組,取第一個值就行,否則這樣打印['胡老師'] print(level[0]) print(info[0]) # 建立item映射 item['name'] = name item['level'] = level item['info'] = info yield item ~~~ ![](https://box.kancloud.cn/c1a593fbb46ad6a45ba07ccfe76427e9_786x481.png) 我們用xpath可能匹配出來多個,也可能匹配出一個,xtract()[0] 把xpath對象轉換成Unicode字符串列表,[0] 代表第一行文字 **利用模板生成spider** * 我們可以執行 ~~~ `scrapy genspider tuna "itcast.cn"` ~~~ > 命令直接生成上述Spider模板類,就不用按照條條框框寫了tuna是類名,itcast.cn是限定的域名,這樣就會在spiders目錄下創建一個符合scrapy框架的爬蟲類。 #### 2.2.3 Item類 * 繼承scrapy.Item類 ~~~ # -*- coding: utf-8 -*- import scrapy """ 定義結構化字段,用來保存爬取到的數據 """ class teacherItem(scrapy.Item): name = scrapy.Field() # 這里建立了三個映射關系結構scrapy.Field(),接受Spider的數據 level = scrapy.Field() info = scrapy.Field() ~~~ #### 2.2.4 Pipelines管道類 > * 管道類負責采集到的數據,是寫入文件還是數據庫都隨便了 > * 需要繼承object類 代碼,把爬取到的數據寫入了文件 ~~~ # -*- coding: utf-8 -*- import json class teacherPipeline(object): # 執行一次 def __init__(self): self.file = open("teacher.josn","w") # 來數據就執行 def process_item(self,item,spider): json_dump = json.dumps(dict(item), ensure_ascii=False) + "\n" self.file.write(json_dump) # 爬蟲結束執行 def close_spider(self,spider): self.file.close() ~~~ > 修改配置文件,導入管道類,修改settings文件 ![](https://box.kancloud.cn/10f041d024657d41454acfecdb1cb2da_1066x197.png) > 以下是整個工程的結構,spiders下都是我們的自定義爬蟲類 ![](https://box.kancloud.cn/721f2d8a3176bb2b3015feff41487629_556x449.png) #### 2.2.5 執行爬蟲程序 ~~~ # tunapipeline是我們自定義的爬蟲類 scrapy crawl tunapipeline ~~~ ![](https://box.kancloud.cn/c057e07df85efb7722460a55f43f950a_1733x258.png) **如果不規定管道類,我們可以直接輸出問文件 !!!!!!!** ~~~ scrapy crawl tunapipeline -o teacherllll.xml ~~~ ![](https://box.kancloud.cn/7c419a82b71b70d9082f940f513d6fff_1773x578.png) #### 2.2.6 執行流程 > 1. Scrapy engine 會把class TunaSpider(scrapy.Spider):中規定的url交給下載器 > 2. 下載器把url的數據下載下來返回給我們自定義的`class TunaSpider(scrapy.Spider):`,并調用它的`parse(self,response)`方法,把下載的數據傳給response > 3. class TunaSpider(scrapy.Spider):的parse(self,response)首先對抓取的數據進行解析,然后根據item映射,如果有pipeline就按照pipeline的規則進行輸出 > ## 3. 中間件 ![](https://box.kancloud.cn/59a67506ddf2f8698126694c7a18d6cb_591x356.png) * 在downloadmidware 自定義中間件,對request和response進行修改 ### 3.1 設置User-Agent 處于engine和downloader中間,處理request和response * fake-useragent開源useragent,這樣就不需要我們自己來維護useragent列表了 1. 使用fake-useragent GitHub:https://github.com/hellysmile/fake-useragent 1. 安裝 ~~~ pip install fake-useragent ~~~ 2. 自定義Middlware類 ~~~ class RandomUserAgentMiddlware(object): #隨機更換user-agent def __init__(self, crawler): super(RandomUserAgentMiddlware, self).__init__() self.ua = UserAgent() self.ua_type = crawler.settings.get("RANDOM_UA_TYPE", "random") @classmethod def from_crawler(cls, crawler): return cls(crawler) def process_request(self, request, spider): def get_ua(): return getattr(self.ua, self.ua_type) request.headers.setdefault('User-Agent', get_ua()) ~~~ 3. 設置settings.py配置下載中間件 scrapy有一個默認的下載中間件,他默認的把User-Agent設置為scrapy,**一定要把默認的useragent優先級設置為None**所以我們要把我們定義的中間的優先級設置的高一些,讓自定義的中間件后執行,這樣就把默認的覆蓋了。 ~~~ from scrapy import signals class UserAgentMiddleware(object): """This middleware allows spiders to override the user_agent""" def __init__(self, user_agent='Scrapy'): self.user_agent = user_agent @classmethod def from_crawler(cls, crawler): o = cls(crawler.settings['USER_AGENT']) crawler.signals.connect(o.spider_opened, signal=signals.spider_opened) return o def spider_opened(self, spider): self.user_agent = getattr(spider, 'user_agent', self.user_agent) def process_request(self, request, spider): if self.user_agent: request.headers.setdefault(b'User-Agent', self.user_agent) ~~~ ~~~ DOWNLOADER_MIDDLEWARES = { 'ArticleSpider.middlewares.RandomUserAgentMiddlware': 543, # scrapy默認的下載中間件 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None, } ~~~ ### 3.2 ip代理
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看