1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Scrapy快速入門,爬取糗事百科段子

        共 7615字,需瀏覽 16分鐘

         ·

        2021-10-18 22:45


        Scrapy快速入門

        安裝和文檔:

        1. 安裝:通過pip install scrapy即可安裝。
        2. Scrapy官方文檔:http://doc.scrapy.org/en/latest
        3. Scrapy中文文檔:http://scrapy-chs.readthedocs.io/zh_CN/latest/index.html

        注意:

        • 在ubuntu上安裝scrapy之前,需要先安裝以下依賴:sudo apt-get install python3-dev build-essential python3-pip libxml2-dev libxslt1-dev zlib1g-dev libffi-dev libssl-dev,然后再通過pip install scrapy安裝。
        • 如果在windows系統(tǒng)下,提示這個(gè)錯(cuò)誤ModuleNotFoundError: No module named 'win32api',那么使用以下命令可以解決:pip install pypiwin32。

        快速入門:

        創(chuàng)建項(xiàng)目:

        要使用Scrapy框架創(chuàng)建項(xiàng)目,需要通過命令來創(chuàng)建。首先進(jìn)入到你想把這個(gè)項(xiàng)目存放的目錄。然后使用以下命令創(chuàng)建:

        scrapy?startproject?[項(xiàng)目名稱]

        目錄結(jié)構(gòu)介紹:

        以下介紹下主要文件的作用:

        items.py:用來存放爬蟲爬取下來數(shù)據(jù)的模型。
        middlewares.py:用來存放各種中間件的文件。
        pipelines.py:用來將items的模型存儲(chǔ)到本地磁盤中。
        settings.py:本爬蟲的一些配置信息(比如請(qǐng)求頭、多久發(fā)送一次請(qǐng)求、ip代理池等)。
        scrapy.cfg:項(xiàng)目的配置文件。
        spiders包:以后所有的爬蟲,都是存放到這個(gè)里面。

        Scrapy框架架構(gòu)

        Scrapy框架介紹:

        寫一個(gè)爬蟲,需要做很多的事情。比如:發(fā)送網(wǎng)絡(luò)請(qǐng)求(urllib庫(kù)、requests庫(kù))、數(shù)據(jù)解析(BeautifulSoup庫(kù)、xpath解析、正則表達(dá)式、css選擇器)、數(shù)據(jù)存儲(chǔ)(excel表格、csv文件、json文件、MySQL數(shù)據(jù)庫(kù)、MongoDB數(shù)據(jù)庫(kù))、反反爬蟲機(jī)制(更換ip代理、設(shè)置請(qǐng)求頭等)、異步請(qǐng)求等。
        這些工作如果每次都要自己從零開始寫的話,比較浪費(fèi)時(shí)間。因此Scrapy把一些基礎(chǔ)的東西封裝好了,在他上面寫爬蟲可以變的更加的高效(爬取效率和開發(fā)效率)。
        因此真正在公司里,一些上了量的爬蟲,都是使用Scrapy框架來解決。

        Scrapy框架模塊功能:

        1. Scrapy Engine(引擎):Scrapy框架的核心部分。負(fù)責(zé)在Spider和ItemPipeline、Downloader、Scheduler中間通信、傳遞數(shù)據(jù)等。
        2. Spider(爬蟲):發(fā)送需要爬取的鏈接給引擎,最后引擎把其他模塊請(qǐng)求回來的數(shù)據(jù)再發(fā)送給爬蟲,爬蟲就去解析想要的數(shù)據(jù)。這個(gè)部分是我們開發(fā)者自己寫 ?的,因?yàn)橐廊∧男╂溄?,頁面中的哪些?shù)據(jù)是我們需要的,都是由程序員自己決定。
        3. Scheduler(調(diào)度器):負(fù)責(zé)接收引擎發(fā)送過來的請(qǐng)求,并按照一定的方式進(jìn)行排列和整理,負(fù)責(zé)調(diào)度請(qǐng)求的順序等。
        4. Downloader(下載器):負(fù)責(zé)接收引擎?zhèn)鬟^來的下載請(qǐng)求,然后去網(wǎng)絡(luò)上下載對(duì)應(yīng)的數(shù)據(jù)再交還給引擎。
        5. Item Pipeline(管道):負(fù)責(zé)將Spider(爬蟲)傳遞過來的數(shù)據(jù)進(jìn)行保存。具體保存在哪里,應(yīng)該看開發(fā)者自己的需求。
        6. Downloader Middlewares(下載中間件):可以擴(kuò)展下載器和引擎之間通信功能的中間件。
        7. Spider Middlewares(Spider中間件):可以擴(kuò)展引擎和爬蟲之間通信功能的中間件。

        Scrapy Shell

        我們想要在爬蟲中使用xpath、beautifulsoup、正則表達(dá)式、css選擇器等來提取想要的數(shù)據(jù)。但是因?yàn)閟crapy是一個(gè)比較重的框架。每次運(yùn)行起來都要等待一段時(shí)間。因此要去驗(yàn)證我們寫的提取規(guī)則是否正確,是一個(gè)比較麻煩的事情。因此Scrapy提供了一個(gè)shell,用來方便的測(cè)試規(guī)則。當(dāng)然也不僅僅局限于這一個(gè)功能。

        打開Scrapy Shell:

        打開cmd終端,進(jìn)入到Scrapy項(xiàng)目所在的目錄,然后進(jìn)入到scrapy框架所在的虛擬環(huán)境中,輸入命令scrapy shell [鏈接]。就會(huì)進(jìn)入到scrapy的shell環(huán)境中。在這個(gè)環(huán)境中,你可以跟在爬蟲的parse方法中一樣使用了。

        使用Scrapy框架爬取糗事百科段子:

        使用命令創(chuàng)建一個(gè)爬蟲:

        scrapy?startproject?qsbk

        scrapy?gensipder?qsbk?"qiushibaike.com"???

        創(chuàng)建了一個(gè)名字叫做qsbk的爬蟲,并且能爬取的網(wǎng)頁只會(huì)限制在qiushibaike.com這個(gè)域名下。

        爬蟲代碼如下:

        import?scrapy

        class?QsbkSpider(scrapy.Spider):
        ????name?=?'qsbk'
        ????allowed_domains?=?['qiushibaike.com']
        ????start_urls?=?['http://qiushibaike.com/']

        ????def?parse(self,?response):
        ????????pass

        爬蟲代碼解析:

        其實(shí)這些代碼我們完全可以自己手動(dòng)去寫,而不用命令。只不過是不用命令,自己寫這些代碼比較麻煩。
        要?jiǎng)?chuàng)建一個(gè)Spider,那么必須自定義一個(gè)類,繼承自scrapy.Spider,然后在這個(gè)類中定義三個(gè)屬性和一個(gè)方法。

        1. name:這個(gè)爬蟲的名字,名字必須是唯一的。
        2. allow_domains:允許的域名。爬蟲只會(huì)爬取這個(gè)域名下的網(wǎng)頁,其他不是這個(gè)域名下的網(wǎng)頁會(huì)被自動(dòng)忽略。
        3. start_urls:爬蟲從這個(gè)變量中的url開始。
        4. parse:引擎會(huì)把下載器下載回來的數(shù)據(jù)扔給爬蟲解析,爬蟲再把數(shù)據(jù)傳給這個(gè)parse方法。這個(gè)是個(gè)固定的寫法。這個(gè)方法的作用有兩個(gè),第一個(gè)是提取想要的數(shù)據(jù)。第二個(gè)是生成下一個(gè)請(qǐng)求的url。

        修改settings.py代碼:

        在做一個(gè)爬蟲之前,一定要記得修改setttings.py中的設(shè)置。兩個(gè)地方是強(qiáng)烈建議設(shè)置的。

        1. ROBOTSTXT_OBEY設(shè)置為False。默認(rèn)是True。即遵守機(jī)器協(xié)議,那么在爬蟲的時(shí)候,scrapy首先去找robots.txt文件,如果沒有找到。則直接停止爬取。
        2. DEFAULT_REQUEST_HEADERS添加User-Agent。這個(gè)也是告訴服務(wù)器,我這個(gè)請(qǐng)求是一個(gè)正常的請(qǐng)求,不是一個(gè)爬蟲。

        完成的爬蟲代碼:

        項(xiàng)目結(jié)構(gòu)

        1.爬蟲部分代碼:

        # 1.爬蟲部分代碼:
        import?scrapy
        from?qsbk.items?import?QsbkItem
        from?scrapy.http.response.html?import?HtmlResponse
        from?scrapy.selector.unified?import?SelectorList

        class?QsbkSpiderSpider(scrapy.Spider):
        ????#name:這個(gè)爬蟲的名字,名字必須唯一
        ????name?=?'qsbk_spider'
        ????#allowed_domains:允許的域名范圍
        ????allowed_domains?=?['qiushibaike.com']
        ????#start_urls:爬蟲從這個(gè)變量中的url開始
        ????start_urls?=?['https://www.qiushibaike.com/text/page/1/']
        ????base_domain?=?"https://www.qiushibaike.com"

        ????def?parse(self,?response):
        ?????????duanzidivs?=?response.xpath("http://div[@class='col1?old-style-col1']/div")
        ????????for?duanzidiv?in?duanzidivs:
        ????????????#?Selector
        ????????????author?=?duanzidiv.xpath(".//h2/text()").get().strip()????#strip()是去除前后空白
        ????????????content?=?duanzidiv.xpath(".//div[@class='content']//text()").getall()
        ????????????content?=?"".join(content).strip()????#content就變成字符串str了
        ????????????#?print(content)
        ????????????item?=?QsbkItem(author=author,?content=content)
        ????????????#?duanzi?=?{"author":author,?"content":content}????#定義一個(gè)字典存放
        ????????????yield?item
        ????????next_url?=?response.xpath("http://ul[@class='pagination']/li[last()]/a/@href").get()
        ????????if?not?next_url:
        ????????????return
        ????????else:
        ????????????yield?scrapy.Request(self.base_domain+next_url,callback=self.parse)

        下面是scrapy shell 測(cè)試的代碼

        2.items.py部分代碼:

        # 2.items.py部分代碼:
        import?scrapy
        class?QsbkItem(scrapy.Item):
        ????author?=?scrapy.Field()
        ????content?=?scrapy.Field()

        3.pipeline部分代碼:

        import?json

        ##########?方法一?##########
        #?class?QsbkPipeline(object):
        #?????def?__init__(self):
        #?????????self.fp?=?open("duanzi.json",?"w",?encoding='utf-8')
        #
        #?????def?open_spider(self,?spider):
        #?????????print('爬蟲開始了……')
        #
        #?????def?process_item(self,?item,?spider):
        #?????????item_json?=?json.dumps(dict(item),?ensure_ascii=False)
        #?????????self.fp.write(item_json+'\n')
        #?????????return?item
        #
        #?????def?close_spider(self,?spider):
        #?????????self.fp.close()
        #?????????print('爬蟲結(jié)束了…')


        ##########?方法二?##########
        ####?數(shù)據(jù)量比較少的時(shí)候?可以用JsonItemExporter
        from?scrapy.exporters?import?JsonItemExporter

        #?class?QsbkPipeline(object):
        #?????def?__init__(self):
        #?????????self.fp?=?open("duanzi.json",?"wb")???#以二進(jìn)制的方式寫入
        #?????????self.exportr?=?JsonItemExporter(self.fp,?ensure_ascii=False,?encoding='utf-8')
        #?????????self.exportr.start_exporting()
        #
        #?????def?open_spider(self,?spider):
        #?????????print('爬蟲開始了……')
        #
        #?????def?process_item(self,?item,?spider):
        #?????????#?item_json?=?json.dumps(dict(item),?ensure_ascii=False)
        #?????????#?self.fp.write(item_json+'\n')
        #?????????self.exportr.export_item(item)
        #?????????return?item
        #
        #?????def?close_spider(self,?spider):
        #?????????self.exportr.finish_exporting()
        #?????????self.fp.close()
        #?????????print('爬蟲結(jié)束了…')


        ##########?方法三?##########
        ####?數(shù)據(jù)量比較多的時(shí)候,需要用JsonLinesItemExporter
        from?scrapy.exporters?import?JsonLinesItemExporter

        class?QsbkPipeline(object):
        ????def?__init__(self):
        ????????self.fp?=?open("duanzi.json",?"wb")???#以二進(jìn)制的方式寫入
        ????????self.exportr?=?JsonLinesItemExporter(self.fp,?ensure_ascii=False,?encoding='utf-8')

        ????def?open_spider(self,?spider):
        ????????print('爬蟲開始了……')

        ????def?process_item(self,?item,?spider):
        ????????self.exportr.export_item(item)
        ????????return?item

        ????def?close_spider(self,?spider):
        ????????self.fp.close()
        ????????print('爬蟲結(jié)束了…')

        4、setting部分代碼

        BOT_NAME?=?'qsbk'

        SPIDER_MODULES?=?['qsbk.spiders']
        NEWSPIDER_MODULE?=?'qsbk.spiders'
        ROBOTSTXT_OBEY?=?False

        DEFAULT_REQUEST_HEADERS?=?{
        ??'Accept':?'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        ??'Accept-Language':?'en',
        ??'User-Agent':'Mozilla/5.0?(Windows?NT?6.1;?Win64;?x64)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/71.0.3578.80?Safari/537.36'
        }

        ITEM_PIPELINES?=?{
        ???'qsbk.pipelines.QsbkPipeline':?300,
        }

        DOWNLOADER_MIDDLEWARES?=?{
        ???'qsbk.middlewares.RandomUserAgentMiddleware':?543,
        }

        MY_USER_AGENT?=?[
        ????"Mozilla/4.0?(compatible;?MSIE?6.0;?Windows?NT?5.1;?SV1;?AcooBrowser;?.NET?CLR?1.1.4322;?.NET?CLR?2.0.50727)",
        ????"Mozilla/4.0?(compatible;?MSIE?7.0;?Windows?NT?6.0;?Acoo?Browser;?SLCC1;?.NET?CLR?2.0.50727;?Media?Center?PC?5.0;?.NET?CLR?3.0.04506)",
        ????"Mozilla/4.0?(compatible;?MSIE?7.0;?AOL?9.5;?AOLBuild?4337.35;?Windows?NT?5.1;?.NET?CLR?1.1.4322;?.NET?CLR?2.0.50727)",
        ]

        5、middlewares部分代碼

        import?random
        class?RandomUserAgentMiddleware(object):
        ????def?__init__(self,?user_agents):
        ????????self.user_agents?=?user_agents

        ????@classmethod
        ????def?from_crawler(cls,?crawler):
        ????????#?從settings.py中導(dǎo)入MY_USER_AGENT
        ????????s?=?cls(user_agents=crawler.settings.get('MY_USER_AGENT'))
        ????????return?s

        ????def?process_request(self,?request,?spider):
        ????????agent?=?random.choice(self.user_agents)
        ????????request.headers['User-Agent']?=?agent
        ????????return?None

        運(yùn)行scrapy項(xiàng)目:

        運(yùn)行scrapy項(xiàng)目。需要在終端,進(jìn)入項(xiàng)目所在的路徑,然后scrapy crawl [爬蟲名字]即可運(yùn)行指定的爬蟲。如果不想每次都在命令行中運(yùn)行,那么可以把這個(gè)命令寫在一個(gè)文件中。以后就在pycharm中執(zhí)行運(yùn)行這個(gè)文件就可以了。比如現(xiàn)在新創(chuàng)建一個(gè)文件叫做start.py,然后在這個(gè)文件中填入以下代碼:

        from?scrapy?import?cmdline

        cmdline.execute("scrapy?crawl?qsbk".split())

        爬取結(jié)果


        瀏覽 39
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产性―交―乱―色―情人 | 国产成人精品免高潮在线人与禽一 | 欧美黄色电影在线 | 免费无码婬A片在线视频夜网站 | 中文字幕第11页 | 偷拍情侣野外做爰视频 | 日欧 二区三区影院 | 蜜桃人妻无码AV天堂三区 | 天堂毛片 | 99re这里 |