[python爬蟲之路day19:] scrapy框架初入門day1——爬取百思不得姐段子

好久沒學習爬蟲了,今天再來記錄一篇我的初入門scrapy。
首先scrapy是針對大型數據的爬取,簡單便捷,但是需要操作多個文件以下介紹:
寫一個爬蟲,需要做很多的事情。比如:
發送網絡請求,
數據解析,
數據存儲,
反反爬蟲機制(更換ip代理、設置請求頭等)
異步請求等。
這些工作如果每次都要自己從零開始寫的話,比較浪費時間。因此Scrapy把一些基礎的東西封裝好了,在他上面寫爬蟲可以變的更加的高效(爬取效率和開發效率)。因此真正在公司裏,一些上了量的爬蟲,都是使用Scrapy框架來解決。

框架圖

  1. Scrapy Engine(引擎)Scrapy框架的核心部分。負責在SpiderItemPipelineDownloaderScheduler中間通信、傳遞數據等。
  2. Spider(爬蟲):發送需要爬取的鏈接給引擎,最後引擎把其他模塊請求回來的數據再發送給爬蟲,爬蟲就去解析想要的數據。這個部分是我們開發者自己寫的,因爲要爬取哪些鏈接,頁面中的哪些數據是我們需要的,都是由程序員自己決定。
  3. Scheduler(調度器):負責接收引擎發送過來的請求,並按照一定的方式進行排列和整理,負責調度請求的順序等。
  4. Downloader(下載器):負責接收引擎傳過來的下載請求,然後去網絡上下載對應的數據再交還給引擎。
  5. Item Pipeline(管道):負責將Spider(爬蟲)傳遞過來的數據進行保存。具體保存在哪裏,應該看開發者自己的需求。
  6. Downloader Middlewares(下載中間件):可以擴展下載器和引擎之間通信功能的中間件。
  7. Spider Middlewares(Spider中間件):可以擴展引擎和爬蟲之間通信功能的中間件。

一. 創建項目:

要使用Scrapy框架創建項目,需要通過命令來創建。首先進入到你想把這個項目存放的目錄。然後使用以下命令創建:

scrapy startproject [項目名稱]

下面進行目錄介紹:
8. items.py:用來存放爬蟲爬取下來數據的模型。
9. middlewares.py:用來存放各種中間件的文件。
10. pipelines.py:用來將items的模型存儲到本地磁盤中。
11. settings.py:本爬蟲的一些配置信息(比如請求頭、多久發送一次請求、ip代理池等)。
12. scrapy.cfg:項目的配置文件。
13. spiders包:以後所有的爬蟲,都是存放到這個裏面。

下面來看具體操作:.
二.使用命令創建一個爬蟲:
#注意此處是
cd qsbk
之後在命令行進行下面操作,不重名

scrapy gensipder qsbk_spider "budejie.com"

創建了一個名字叫做qsbk的爬蟲,並且能爬取的網頁只會限制在budejie.com這個域名下。
這是通過該命令產生的代碼:
爬蟲代碼解析:

import scrapy

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

    def parse(self, response):
        pass

其實這些代碼我們完全可以自己手動去寫,而不用命令。只不過是不用命令,自己寫這些代碼比較麻煩。
要創建一個Spider,那麼必須自定義一個類,繼承自scrapy.Spider,然後在這個類中定義三個屬性和一個方法。

注意:

  1. name:這個爬蟲的名字,名字必須是唯一的。
  2. allow_domains:允許的域名。爬蟲只會爬取這個域名下的網頁,其他不是這個域名下的網頁會被自動忽略。
  3. start_urls:爬蟲從這個變量中的url開始。
  4. parse:引擎會把下載器下載回來的數據扔給爬蟲解析,爬蟲再把數據傳給這個parse方法。這個是個固定的寫法。這個方法的作用有兩個,第一個是提取想要的數據。第二個是生成下一個請求的url。
    二.
    #修改settings.py代碼:

在做一個爬蟲之前,一定要記得修改setttings.py中的設置。兩個地方是強烈建議設置的。

  1. ROBOTSTXT_OBEY設置爲False。默認是True。即遵守機器協議,那麼在爬蟲的時候,scrapy首先去找robots.txt文件,如果沒有找到。則直接停止爬取。
  2. DEFAULT_REQUEST_HEADERS添加User-Agent。這個也是告訴服務器,我這個請求是一個正常的請求,不是一個爬蟲。

完成的爬蟲代碼:
qsbk_spider.py

# -*- coding: utf-8 -*-
import scrapy
from qsbk.items import QsbkItem
from scrapy.http.response.html import HtmlResponse
from scrapy.selector.unified import SelectorList
class QsbkScrapySpider(scrapy.Spider):
    name = 'qsbk_spider'
    allowed_domains = ['budejie.com']
    start_urls = ['http://www.budejie.com/1']
    base_url = "http://www.budejie.com/"
    def parse(self, response):
        #SelectorList
        duanzilis=response.xpath("//div[@class='j-r-list']//li")

        for duanzi in duanzilis:
           #Selector
            author = duanzi.xpath(".//div[@class='u-txt']/a[@class='u-user-name']/text()").get()
            if author is not None:   #沒有匹配到元素的情況的處理
               author=author.strip()   #同上
               # print(author)            #同上
            duanzi_text=duanzi.xpath(".//div[@class='j-r-list-c-desc']/a/text()").get()
            if duanzi_text is not None:
                duanzi_text="".join(duanzi_text)
                #print(duanzi_text)
            if duanzi_text and author is not None:
                duanziz={"author":author,"duanzi_text":duanzi_text}
                print(duanziz)
                item=QsbkItem(author=author,duanzi_text=duanzi_text)
                yield item
            next_url=response.xpath('//div[@class="m-page m-page-sr m-page-sm"]/a[last()]/@href').get()
            # if not next_url:
            #     return
            # else:
            yield scrapy.Request(self.base_url+next_url,callback=self.parse)




settings.py

# -*- coding: utf-8 -*-

# Scrapy settings for qsbk project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
#     https://docs.scrapy.org/en/latest/topics/settings.html
#     https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
#     https://docs.scrapy.org/en/latest/topics/spider-middleware.html

BOT_NAME = 'qsbk'

SPIDER_MODULES = ['qsbk.spiders']
NEWSPIDER_MODULE = 'qsbk.spiders'


# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'qsbk (+http://www.yourdomain.com)'

# Obey robots.txt rules
ROBOTSTXT_OBEY = False

# Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32

# Configure a delay for requests for the same website (default: 0)
# See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 1
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16

# Disable cookies (enabled by default)
#COOKIES_ENABLED = False

# Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False

# Override the default request headers:
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 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36"
}

# Enable or disable spider middlewares
# See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = {
#    'qsbk.middlewares.QsbkSpiderMiddleware': 543,
#}

# Enable or disable downloader middlewares
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = {
#    'qsbk.middlewares.QsbkDownloaderMiddleware': 543,
#}

# Enable or disable extensions
# See https://docs.scrapy.org/en/latest/topics/extensions.html
#EXTENSIONS = {
#    'scrapy.extensions.telnet.TelnetConsole': None,
#}

# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
   'qsbk.pipelines.QsbkPipeline': 300,
}

# Enable and configure the AutoThrottle extension (disabled by default)
# See https://docs.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True
# The initial download delay
#AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
#AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
#AUTOTHROTTLE_DEBUG = False

# Enable and configure HTTP caching (disabled by default)
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache'
#HTTPCACHE_IGNORE_HTTP_CODES = []
#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'

start.py
可以在終端運行,此處在pycharm運行。

from scrapy import cmdline
cmdline.execute("scrapy crawl qsbk_spider".split())

pipelines.py
此處介紹三種方法

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html.傳統方法
# 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("爬蟲結束了……").JsonItemExporter,保存的是列表形式,不換行
# from scrapy.exporters import JsonItemExporter
#
#
# class QsbkPipeline(object):
#     def __init__(self):
#         self.fp=open("duanzi.json","wb")
#         self.exporter=JsonItemExporter(self.fp,ensure_ascii=False,encoding='utf-8')
#     def open_spider(self,spider):
#         print("爬蟲開始了……")
#     def process_item(self, item, spider):
#         self.exporter.export_item(item)
#         return item
#     def close_spider(self,spider):
#         self.fp.close()
#         print("爬蟲結束了……").保存的是字典形式,和第一種一樣,每行一個數據

from scrapy.exporters import JsonLinesItemExporter


class QsbkPipeline(object):
    def __init__(self):
        self.fp=open("duanzi.json","wb")
        self.exporter=JsonLinesItemExporter(self.fp,ensure_ascii=False,encoding='utf-8')
    def open_spider(self,spider):
        print("爬蟲開始了……")
    def process_item(self, item, spider):
        self.exporter.export_item(item)
        return item
    def close_spider(self,spider):
        self.fp.close()
        print("爬蟲結束了……")

items.py

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html

import scrapy


class QsbkItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    author=scrapy.Field()
    duanzi_text=scrapy.Field()


保存結果截圖:
在這裏插入圖片描述
此文部分選自up主神奇的老黃的筆記,有刪改,僅供同行者查閱及自我複習。
(累趴…

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