好久沒學習爬蟲了,今天再來記錄一篇我的初入門scrapy。
首先scrapy是針對大型數據的爬取,簡單便捷,但是需要操作多個文件以下介紹:
寫一個爬蟲,需要做很多的事情。比如:
發送網絡請求,
數據解析,
數據存儲,
反反爬蟲機制(更換ip代理、設置請求頭等)
異步請求等。
這些工作如果每次都要自己從零開始寫的話,比較浪費時間。因此Scrapy
把一些基礎的東西封裝好了,在他上面寫爬蟲可以變的更加的高效(爬取效率和開發效率)。因此真正在公司裏,一些上了量的爬蟲,都是使用Scrapy
框架來解決。
Scrapy Engine(引擎)
:Scrapy
框架的核心部分。負責在Spider
和ItemPipeline
、Downloader
、Scheduler
中間通信、傳遞數據等。Spider(爬蟲)
:發送需要爬取的鏈接給引擎,最後引擎把其他模塊請求回來的數據再發送給爬蟲,爬蟲就去解析想要的數據。這個部分是我們開發者自己寫的,因爲要爬取哪些鏈接,頁面中的哪些數據是我們需要的,都是由程序員自己決定。Scheduler(調度器)
:負責接收引擎發送過來的請求,並按照一定的方式進行排列和整理,負責調度請求的順序等。Downloader(下載器)
:負責接收引擎傳過來的下載請求,然後去網絡上下載對應的數據再交還給引擎。Item Pipeline(管道)
:負責將Spider(爬蟲)
傳遞過來的數據進行保存。具體保存在哪裏,應該看開發者自己的需求。Downloader Middlewares(下載中間件)
:可以擴展下載器和引擎之間通信功能的中間件。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
,然後在這個類中定義三個屬性和一個方法。
注意:
- name:這個爬蟲的名字,名字必須是唯一的。
- allow_domains:允許的域名。爬蟲只會爬取這個域名下的網頁,其他不是這個域名下的網頁會被自動忽略。
- start_urls:爬蟲從這個變量中的url開始。
- parse:引擎會把下載器下載回來的數據扔給爬蟲解析,爬蟲再把數據傳給這個
parse
方法。這個是個固定的寫法。這個方法的作用有兩個,第一個是提取想要的數據。第二個是生成下一個請求的url。
二.
#修改settings.py
代碼:
在做一個爬蟲之前,一定要記得修改setttings.py
中的設置。兩個地方是強烈建議設置的。
ROBOTSTXT_OBEY
設置爲False。默認是True。即遵守機器協議,那麼在爬蟲的時候,scrapy首先去找robots.txt文件,如果沒有找到。則直接停止爬取。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主神奇的老黃的筆記,有刪改,僅供同行者查閱及自我複習。
(累趴…