Scrapy框架入门

1. 创建爬虫

cmd 或 powershell 或 bash 创建爬虫命令:

cmd打开方式:win + R ,输入cmd,回车。

powershell:win + S,输入powershell,回车。

bash:Linux下,ctrl + alt + T。

scrapy startproject 爬虫名称

2. 核心类Spider

以爬取Scrapy百度百科为例。

首先在setting中关闭网页爬虫检查:

ROBOTSTXT_OBEY = False

然后在spiders目录下创建Spider01文件:

# Spider01.py
import scrapy


# Spider01类继承自scrapy.Spider类
class Spider01(scrapy.Spider):
    # 爬虫名称
    name = 'spider01'
    # 要爬的网址,是一个列表,可以写多个
    start_urls = ['https://baike.baidu.com/item/scrapy/7914913?fr=aladdin']
    def parse(self, response):
        # 输出网页的html
        print(response.text)

再创建文件启动程序RUN.py

# RUN.py
import scrapy.cmdline as cmdline


def run_spider(spider_name: str):
    cmdline.execute(("scrapy crawl " + spider_name).split())


if __name__ == '__main__':
    run_spider('spider01')

文件目录如图所示

Scrapy框架入门_第1张图片

此时运行RUN.py,若在控制台能正确输出网页的html,则说明到此为止是成功的。

Scrapy框架入门_第2张图片

2.1 抽取数据

使用xpath或者css选择器,选择器的语法在此不赘述。此处只介绍scrapy的API。

import scrapy


class Spider01(scrapy.Spider):
    name = 'spider01'
    start_urls = ['https://baike.baidu.com/item/scrapy/7914913?fr=aladdin']
    def parse(self, response):
        # 抽取html中全部的子标题,getall()方法将子标题以列表的形式返回
        print(response.xpath('//h2[@class="title-text"]/text()').getall())
        # 如果使用get()取代getall(),则只返回html中第一个与之匹配的内容
        print(response.xpath('//h2[@class="title-text"]/text()').getall())

3. items的使用

items用于格式化存储爬取的数据

首先在item中构造类ScrapydemoItem。

# itmes.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 ScrapydemoItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    title = scrapy.Field()
    content = scrapy.Field()

其次,在spider的parse中调用它,在调用之前,需要导入该类。

import scrapy
from ScrapyDemo.items import ScrapydemoItem

class Spider01(scrapy.Spider):
    name = 'spider01'
    start_urls = ['https://baike.baidu.com/item/scrapy/7914913?fr=aladdin']
    def parse(self, response):
        
        item = ScrapydemoItem()
        item['title'] = response.xpath('//h2[@class="title-text"]/text()').get()
        item['content'] = response.xpath('//h2[@class="title-text"]/../following-sibling::*[1]/text()').get()
        
        print(item['title'])
        print(item['content'])

4. middlewares中间件的开发

middleware位于request与response之间,用于更换代理IP更换Cookies更换User-Agent自动重试

4.1 更换代理IP

from scrapy import signals
import random
from scrapy.utils.project import get_project_settings


class ScrapydemoDownloaderMiddleware(object):
    # 其他方法保持默认即可
    def process_request(self, request, spider):
        # 发送每个请求时,都会经过该方法
        # 因此,该方法适合放置代理IP
        proxy = random.choice(get_project_settings()['PROXIES'])
        request.meta['proxy'] = proxy
        # 使用了settings.py配置文件,因此需要导入它 from scrapy.utils.project import get_project_settings
        # 在settings.py中添加代理IP
        # PROXIES = ['https://114.217.243.25:8118',
        #  'https://125.37.175.233:8118',
        #  'http://1.85.116.218:8118']
        # 需要看清楚是HTTP型还是HTTPS型的代理IP
        return None

写完后,需要去setting.py中找到下面一段代码,并取消注释,即可成功激活。所有中间件都需要激活,不再赘述。

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

4.2 更换User-Agent

from scrapy import signals
import random
from scrapy.utils.project import get_project_settings


class ScrapydemoDownloaderMiddleware(object):
    def process_request(self, request, spider):
        ua = random.choice(get_project_settings()['USER_AGENT_LIST'])
        request.headers['User-Agent'] = ua

        return None

在settings.py中添加请求头

4.3 更换cookie

4.4 自动重试

# setting.py
RETRY_ENABLED = True
RETRY_TIMES = 10
RETRY_HTTP_CODES = [
    412
]

5. Pipeline

管道组件,由三个核心方法构成:open_spider、process_item、close_spider。

  1. 当爬虫启动时,会触发open_spider组件,此时通常是获取数据库连接,或者打开文件。

  2. 当爬虫每yield一个item时,都会经过process_item函数,在这个函数中,我们通常会检查新来的item是否与已有的item重复了。或者将item写入数据库。

  3. 当爬虫关闭时,会经过close_spider函数,此时通常是关闭数据库或者文件。

Pipeline组件可以有多个,相当于管道的串联,每个Pipeline都需要在settings.py中开放。

# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
   'scrapyDemo.pipelines.ScrapydemoPipeline': 300, # 300代表优先级,数字越小越先执行
}

下面是一个删除重复item的Pipeline

class ScrapydemoPipeline(object):

    # 爬虫启动时执行
    def open_spider(self, spider):
        self.contentSet = set()
        print("hello")

    # 每yield一个item时都会经过这个函数
    def process_item(self, item, spider):
        if item["content"] not in self.contentSet:
            self.contentSet.add(item["content"])
            # 在这里可以将item写入文件或数据库
            # Pipeline组件可以有多个,在settings.py文件中设置优先级
            return item
        else:
            # item重复了
            pass
	
    # 爬虫结束时执行
    def close_spider(self, spider):
         print("bye")

你可能感兴趣的:(爬虫)