scrapy爬虫入门学习笔记(一)

本文是关于Scrapy爬虫框架的入门学习笔记,涵盖了Scrapy的基本组件介绍,如引擎、调度器、下载器等,以及项目文档目录解析,包括items.py、pipelines.py、settings.py和spiders目录的作用。还介绍了Scrapy项目创建过程,包括定义Item、编写Spider和Pipeline,以及如何处理数据和爬取多页信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

scrapy爬虫入门学习笔记(一)

scrapy的安装很简单,网上有大量相关的教程,自行搜索。

1.scrapy框架

这里写图片描述
- 引擎(scrapy engine)
处理系统的数据流,触发事件
- 调度器(scheduler)
接受引擎发来的请求,压入队列,并在引擎再次请求时返回。可以想象成一个URL的优先队列,由它决定下一个抓取的网址是什么,并进行去重。
- 下载器(downloader)
用于下载网页内容,并返回给spider,下载器建立于twisted这个高效的异步模型之上
- 爬虫(spiders)
从特定网页爬取自己想要的信息,即item,提交给引擎
- 管道(pipeline)
处理从网页中提取的item,对信息进行存储、写等处理
- 下载中间件(downloader middlewares)
处理引擎和下载器之间的请求和响应
- 爬虫中间件(spider middlewares)
处理spider的响应输入和请求输出
- 调度中间件(scheduler middlewares)
对引擎的请求进行调度处理

2.scrapy项目文档目录

tree
这里写图片描述
- scrapy.cfg:项目的配置文件
- items.py:项目的目标文件。
- pipelines.py:项目的管道文件,作用就一个,处理item字段
- settings.py:项目的设置文件
- spiders:存储爬虫代码目录

items.py
- 定义结构化的字段,用于保存爬取到的数据,类似于python中的字典,但提供了额外的保护防止错误。
- 创建一个scrapy.Item类,定义类型为scrapy.Field的类属性来定义一个Item
- 创建一个ITcastItem类,构建Item模型

import scrapy
class ItcastItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    name=scrapy.Field()
    # l老师的职称
    title=scrapy.Field()
    # 老师信息
    info=scrapy.Field()
    # pass

itcast.py
- 爬虫python文件
- 定义一个ITcastSpider类,继承自scrapy.spider
- 需要name、start_urlds和parse
- parse函数中的xpath是xml文档查找信息的语言,可用于对xml元素和属性值进行遍历

class ItcastSpider(scrapy.Spider):
    # 爬虫名,启动爬虫时需要的必须参数
    name = 'itcast'
    # 爬取域范围,允许爬虫在这个域名下进行爬取(可选)
    # allowed_domains = []
    # 起始URL列表,爬虫执行后第一批请求,将从这个列表中获取
    start_urls = ['http://www.itcast.cn/channel/teacher.shtml']

    def parse(self, response):
        node_list=response.xpath("//div[@class='li_txt']")
        # 存储所有的items字段
        items=[]
        for node in node_list:
            # 创建item字段,用来存储信息
            item=ItcastItem()
            # xpath对象转成Unicode字符串,使用extract()
            name=node.xpath("./h3/text()").extract()

            title=node.xpath("./h4/text()").extract()
            info=node.xpath("./p/text()").extract()
            item['name']=name[0]
            item['title']=title[0]
            item['info']=info[0]
            items.append(item)
        # 返回给引擎了
        return items
yield item//item返回给pipeline

- yield和return的区别:yield提交但并不返回,依然继续执行。return之后函数就结束了。yield只是在程序执行中提交一个结果。如果所有数据全部保存在一个列表中,等到程序执行完毕后return,这样内存开销会很大,而且意外中断数据就丢失了。
pipelines.py和settings.py
Item 在spider中收集到后,将会传递到pipeline,pipeline组件按照响应码的顺序处理item,主要包含以下操作:
- 验证爬取的数据,比如是否包含某些字段,如name
- 查重并丢弃,URL的查重由调度器完成。数据的查重需要自己做,使用集合set
- 将爬取的结果保存到文件或数据库中。

#pipelines.py
import json
import codecs

class ItcastPipeline(object):
    # 第二个是必选的,1和3是可选的,如果需要操作本地磁盘就需要1和3
    # 初始化只执行一次
    def __init__(self):
        self.f=codecs.open("itcast_pipeline.json",'w',encoding='utf-8')

    # 获取每一个item
    def process_item(self, item, spider):
        content=json.dumps(dict(item),ensure_ascii=False)+', \n'
        self.f.write(content)
        # 返回一个item给引擎,告诉引擎item已经处理好了,可以处理下一个item
        # 如果有其他管道文件,就会交给下一个item
        # 也就是说每一个管道类都需要一个returnitem
        return item
    # 爬虫关闭也只执行一次
    def close_spider(self,spider):
        self.f.close()
# 可以定义处理数据库的管道文件,但是需要在setings.py中设定

pipelines.py中的设定需要在settings.py中对应的设置才会生效。

#setings.py
#配置pipeline,每个管道类后跟一个响应码,依照从小到大优先
ITEM_PIPELINES = {
   'ITcast.pipelines.ItcastPipeline': 300,
}

3.项目初体验

项目目的
爬取Tencent招聘信息,URL:https://hr.tencent.com/position.php?&start=0
创建项目
scrapy startproject tencent
items.py
首先在TencentItem类中定义字段,确定要哪些信息

class TencentItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    positionName=scrapy.Field()
    positiontype=scrapy.Field()
    requireNum=scrapy.Field()
    positionLocation=scrapy.Field()
    positionTime=scrapy.Field()
    # pass

创建spider
scrapy genspider Tencent "tencent.com"
写spider类

# -*- coding: utf-8 -*-
import scrapy
from tencent.items import TencentItem

class TencentSpider(scrapy.Spider):
    name = 'Tencent'
    allowed_domains = ['tencent.com']
    baseurl='https://hr.tencent.com/position.php?&start='
    offset=0
    start_urls=[]
    for i in range(393):
        start_urls.append(baseurl+str(offset+10*i))

    def parse(self, response):
        #xpath读取节点列表
        node_list=response.xpath("//tr[@class='even'] | //tr[@class='odd']")
        # print(len(node_list))
        for node in node_list:
            item=TencentItem()
            item['positionName']=node.xpath("./td[1]/a/text()").extract()[0]
            item['positionLink']=node.xpath("./td[1]/a/@href").extract()[0]
            if len(node.xpath("./td[2]/text()")):
                item['positiontype']=node.xpath("./td[2]/text()").extract()[0]
            item['requireNum']=node.xpath("./td[3]/text()").extract()[0]
            item['positionLocation']=node.xpath("./td[4]/text()").extract()[0]
            item['positionTime']=node.xpath("./td[5]/text()").extract()[0]
            yield item
        # if self.offset<3930:
        #     self.offset+=10
        #     url=self.baseurl+str(self.offset)
        #     yield scrapy.Request(url,callback=self.parse)

这里可以采用多种方法继续爬取下一页的数据,可以采用yield scrapy.Request(url,callback=self.parse)
提交迭代的URL给引擎。也可以把所有的URL一并放到start_urls里面。后一种方法采用并发执行,效率更高。

写pipeline类

import json

class TencentPipeline(object):
    def __init__(self):
        self.f=open("tencent.json",'w',encoding='utf-8')
    def process_item(self, item, spider):
        contents=json.dumps(dict(item),ensure_ascii=False)+',\n'
        self.f.write(contents)
        return item
    def close_spider(self,spider):
        self.f.close()

执行
scrapy crawl Tencent

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值