scrapy爬蟲入門--爬取《糗事百科》內容(上):基礎知識篇

爬取《糗事百科》-基礎知識篇

一、scrapy簡介

1、scrapy python的爬蟲框架,非常出名,我們此處學用法,實現功能即可。有興趣可以下載源碼、理解,底層使用了多進程、多線程、隊列等技術。


2、安裝:pip installscrapy

注意如果出錯:

building 'twisted.test.raiser' extension

error: Microsoft Visual C++ 14.0 is required. Get it with"Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools

解決方案:

    http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted

    下載twisted對應版本的whl文件(如我的Twisted-17.5.0-cp36-cp36m-win_amd64.whl),cp後面是python版本,amd64代表64位,運行命令:

    pip install C:\Users\Downloads\Twisted-17.5.0-cp36-cp36m-win_amd64.whl

 

3、框架的介紹:

由5部分組成

①  引擎

②  下載器(負責下載)、

③  spiders(爬蟲文件)、

④  調度器(調度的、爬蟲、給你一個url、爬完這個需要再去提取指定的url接着爬、調度器統一分發、生成一個請求對象,看讓誰發送這個請求對象)

⑤  管道(pipeline)

我們的代碼寫到spider與管道中,spider裏面實現內容解析、鏈接提取(比如爬取內容、不只爬取第一頁內容,每頁鏈接不一樣);管道:決定數據是保存到mysql、文件、還是mongodb中。


4、scrapy工作原理:

見圖片:

     先給個起始url,在spiders代碼裏放着,引擎會將起始url要過來,不做實際的工作,扔給調度器,調度器有個隊列,負責調度,如果需要下載,出隊給引擎,引擎不負責下載,扔給下載器,從互聯網把數據下載下來,會將數據再扔給引擎,引擎將數據給spiders,spiders裏面有解析內容的代碼,解析時候會有你想要的數據,存放到一個字典中,(不僅有數據。還會有其他的url)總之,解析完之後有兩種結果,url與數據,如果是數據,扔給引擎,引擎扔給管道,管道處理數據,存到哪裏?mysql?mongodb?如果是url,就會給調度器,再重複上述的步驟。

    注意:

        爬蟲核心:都在spiders裏面;

        其他的 扔出去系統都會給處理的;

        管道里面也是需要自己寫的;

        調度器裏面也不需要自行編寫。出隊是系統決定的;

 

5、scrpy簡單使用

(1)創建項目:

在當前文件夾 打開超級終端 

scrapy startproject firstblood

(scrapy路徑、還有包都在此路徑放着,你可以開啓指令開始爬蟲  cd進來,然後看下文)

*認識目錄結構:(*爲你需要打交道的文件)

firstblood

    firstblood(真正的項目文件)

        __pycache__(緩存文件)

        spiders(爬蟲文件存放的位置)

            __pycache__

            __init__.py

            lala.py(爬蟲文件、涉及文件的解析*)

        __int__.py(包的標誌)

        items.py(定義數據結構的的地方*)

        middlewares.py(中間件)

        pipelines.py(管道文件*)

        settings.py(配置文件*)

    scrapy.cfg(不用管)

(2)生成爬蟲文件

cd firstblood
scrapy genspider qiubaiwww.qiushibaike.com

qiubai:(爬蟲的名字)

www.qiushibaike.com:(爬取的域名)

會生成一個qiubai.py文件:

# -*- coding: utf-8 -*-
import scrapy
class QiubaiSpider(scrapy.Spider):
    # 爬蟲的名字
    name = 'qiubai'
    # 允許的域名, 是一個列表,裏面可以放多個,一般都做限制
    allowed_domains = ['www.qiushibaike.com', 'www.baidu.com']
    # 起始url,是一個列表
    start_urls = ['https://www.qiushibaike.com/']
    # 解析函數,重寫這個方法,發送請求之後,響應來了就會調用這個方法,函數有一個參數response就是響應內容,該函數對返回值有一個要求,必須返回可迭代對象
    def parse(self, response):
        pass

class QiubaiSpider()

  1爬蟲的名字

  2允許的域名(多了一個限制,只爬取此域名下,不限制的話就是全爬取。如果域名比較多,此是一個列表,加逗號,往後接着寫域名)

  3起始url(從哪兒開始爬取)

  4 def parse

(解析函數,寫解析的代碼,發送的請求,響應過來之後,就在這裏解析,重寫這個方法,方法名不能改變,在這個方法中,響應就是傳個參數,response(就是響應內容),會自動調用,不用再手動寫,該函數對返回值有一個要求,就是返回可迭代對象)

 

*認識response對象

    程序是如何跑起來的:

    指令模式:

cd firstblood
firstblood
cd spiders
scrpycrawl qiubai

    運行之後、有三處錯誤:

    1.win32,注意版本

    2.取消遵從robots協議  settings.py 在第22行

    3.U-A頭部信息改一下,粘個headers在後面。在第19行

    print(response.text)字符串類型

    print(response.body)打印的字節類型

    xpath():scrapy內部已經集成了xpath,直接使用即可,但是與原生的稍微有不同,後續會展示。


(3)執行輸出指定格式     

scrapycrawl qiubai -o qiubai.json
scrapycrawl qiubai -o qiubai.xml
scrapycrawl qiubai -o qiubai.csv

            【注】你輸出爲csv的時候,中間估計有空行,自己百度一下解決掉即可

 

二、scrapy shell

1、scrapy shell是什麼?

         是一個調試工具,常用來調試xpath對不對。

2、安裝依賴:pip installipython

         更加智能的交互環境可以通過tab提示內容

         終端下任意位置,輸入如下指令:

         scrapyshell 域名

3、屬性

response.url 請求的url

response.body字節類型

response.text

response.status響應狀態碼

response.headers響應頭

方法:xpath()提取出來的都是selector對象,需要進行extract()一下,然後再提取出來字符串

css():根據選擇器進行獲取指定的內容

 示例:

ret=response.css('#content-left>div?.authorimg::attr(src)')

ret=response.css('#content-left'>div>.authorh2::text')

ret[0].extract()

selector對象

    是scrapy自己封裝的一個對象,不論你上面通過xpath還是css,獲取到的都是這個對象

xpath()

css()

extract():將對象直接轉化爲字符串

extract_first():功能就等同於

         extract_first()==[0].extract()=extract()[0]

         如果xpath或者css寫錯了,返回一個空列表,通過後兩種方式就會報錯,但是通過extract_first()獲取,就會獲取none

item對象

         爬取數據的時候,第一步就是要定義數據結構,在item.py中定義,通過這個類創建的對象十分特殊,類似字典,字典怎麼用,它就怎麼用,這個對象可以快速地轉換爲字典

         回到ipthon輸入:

         classPerson(scrapy.Item)(繼承這個類)

                   name=scray.Field()

                   age=scray.Field()

         p=Person()(創建一個對象)

         p['name']='goudan'(賦值)

         p['age']=20

         p['name']打印

         p['age']

         type(p)

         d=dict(p)(轉化爲字典)


三、yield item和請求

1、yield是什麼意思?

  deftest():
                   lt=[]
                   forx in range(1,11):
                            lt.append(x)
                   returnlt

如果寫100個,1000個,一下生成1000個,寫到列表中,都會顯示出來,這樣資源浪費,所以就引入了生成器。生成器,不是保存的數據,而是保存一個算法,用到的時候,直接調用,再給你生成。

def demo():
         forx in range(1,11):
                   yieldx
a=demo()
print(a)

此時demo就不再是個函數 a=demo() print(a)就是一個生成器

print(next(a))取出第一個數據
print(next(a))
print(next(a))
print(next(a))
print(next(a))

....

print(next(a))到第11個再取就會報錯。

也可以遍歷:

 for x in a:
                   print(x)
         defdemo():
                  for x in range(1,11):
                            yield x
                           print'嘻嘻嘻'
                  yield '哈哈哈'

         如果是print(next(a)),則只會打印一個1,嘻嘻嘻不會打印,只有打印下一個的時候,嘻嘻嘻纔會打印

         函數中可以出現yield,證明這個函數是生成器,可以有多個yield


....

print(next(a))到第11個再取就會報錯。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章