Python爬虫采集框架——Scrapy初学入门

news2025/1/16 15:40:43

一、安装Scrapy依赖包

pip install Scrapy

二、创建Scrapy项目(tutorial)

scrapy startproject tutorial

项目目录包含以下内容

tutorial/
    scrapy.cfg            # deploy configuration file
    tutorial/             # project's Python module, you'll import your code from here
        __init__.py
        items.py          # project items definition file
        middlewares.py    # project middlewares file
        pipelines.py      # project pipelines file
        settings.py       # project settings file
        spiders/          # a directory where you'll later put your spiders
            __init__.py

三、tutorial/spiders目录下编写蜘蛛(quotes_spider.py)

1、蜘蛛(version1.0)

import scrapy
class QuotesSpider(scrapy.Spider):
    name = "quotes"
    def start_requests(self):
        urls = [
            'http://quotes.toscrape.com/page/1/',
            'http://quotes.toscrape.com/page/2/',
        ]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)
    def parse(self, response):
        page = response.url.split("/")[-2]
        filename = f'quotes-{page}.html'
        with open(filename, 'wb') as f:
            f.write(response.body)
        self.log(f'Saved file {filename}')

蜘蛛类QuotesSpider必须得继承scrapy.Spider,并定义以下属性和方法:

name:蜘蛛名称(它在一个项目中必须是唯一的)

start_requests():蜘蛛开始请求(方法返回的是请求的iterable)

请求:scrapy.Request(url=url, callback=self.parse)

parse():蜘蛛解析请求的响应(Response参数是响应的页面内容)

2、蜘蛛(version2.0)

import scrapy
class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = [
        'http://quotes.toscrape.com/page/1/',
        'http://quotes.toscrape.com/page/2/',
    ]
    def parse(self, response):
        page = response.url.split("/")[-2]
        filename = f'quotes-{page}.html'
        with open(filename, 'wb') as f:
            f.write(response.body)

只需定义start_urls属性,不需重写start_requests() 方法,由默认的start_requests()方法根据start_urls属性开始请求也可。

3、蜘蛛(version3.0)

页面HTML代码:

<div class="quote">
    <span class="text">“The world as we have created it is a process of our
    thinking. It cannot be changed without changing our thinking.”</span>
    <span>
        by <small class="author">Albert Einstein</small>
        <a href="/author/Albert-Einstein">(about)</a>
    </span>
    <div class="tags">
        Tags:
        <a class="tag" href="/tag/change/page/1/">change</a>
        <a class="tag" href="/tag/deep-thoughts/page/1/">deep-thoughts</a>
        <a class="tag" href="/tag/thinking/page/1/">thinking</a>
        <a class="tag" href="/tag/world/page/1/">world</a>
    </div>
</div>

蜘蛛代码:

import scrapy
class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = [
        'http://quotes.toscrape.com/page/1/',
        'http://quotes.toscrape.com/page/2/',
    ]
    def parse(self, response):
        for quote in response.css('div.quote'):
            yield {
                'text': quote.css('span.text::text').get(),
                'author': quote.css('small.author::text').get(),
                'tags': quote.css('div.tags a.tag::text').getall(),
            }

该蜘蛛将提取页面中的text、author和tags,并使用终端打印。

4、蜘蛛(version4.0)

下一页HTML代码:

<ul class="pager">
    <li class="next">
        <a href="/page/2/">Next <span aria-hidden="true">&rarr;</span></a>
    </li>
</ul>

蜘蛛代码:

import scrapy
class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = [
        'http://quotes.toscrape.com/page/1/',
    ]
    def parse(self, response):
        for quote in response.css('div.quote'):
            yield {
                'text': quote.css('span.text::text').get(),
                'author': quote.css('small.author::text').get(),
                'tags': quote.css('div.tags a.tag::text').getall(),
            }
        next_page = response.css('li.next a::attr(href)').get()
        if next_page is not None:
            next_page = response.urljoin(next_page)
            yield scrapy.Request(next_page, callback=self.parse)

该蜘蛛将提取页面中的text、author和tags,使用终端打印,提取下一页的地址并开始请求,以此递归。

#做如下测试操作
urljoin("http://www.xoxxoo.com/a/b/c.html", "d.html")  
#结果为:'http://www.xoxxoo.com/a/b/d.html'  
urljoin("http://www.xoxxoo.com/a/b/c.html", "/d.html") 
#结果为:'http://www.xoxxoo.com/d.html'   
urljoin("http://www.xoxxoo.com/a/b/c.html", "../d.html") 
#结果为:'http://www.xoxxoo.com/a/d.html' 

5、蜘蛛(version5.0)

import scrapy
class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = [
        'http://quotes.toscrape.com/page/1/',
    ]
    def parse(self, response):
        for quote in response.css('div.quote'):
            yield {
                'text': quote.css('span.text::text').get(),
                'author': quote.css('span small::text').get(),
                'tags': quote.css('div.tags a.tag::text').getall(),
            }
        next_page = response.css('li.next a::attr(href)').get()
        if next_page is not None:
            yield response.follow(next_page, callback=self.parse)

蜘蛛(version4.0)和蜘蛛(version5.0)的区别:scrapy.Request支持绝对URL,而response.follow支持相对URL,并返回一个请求实例。

6、蜘蛛(version6.0)

import scrapy
class AuthorSpider(scrapy.Spider):
    name = 'author'
    start_urls = ['http://quotes.toscrape.com/']
    def parse(self, response):
        author_page_links = response.css('.author + a')
        yield from response.follow_all(author_page_links, self.parse_author)
        pagination_links = response.css('li.next a')
        yield from response.follow_all(pagination_links, self.parse)
    def parse_author(self, response):
        def extract_with_css(query):
            return response.css(query).get(default='').strip()
        yield {
            'name': extract_with_css('h3.author-title::text'),
            'birthdate': extract_with_css('.author-born-date::text'),
            'bio': extract_with_css('.author-description::text'),
        }

使用选择器选择<a>元素,会默认返回href属性,因此response.css('li.next a::attr(href)')response.css('li.next a')是一样的。

response.follow_allresponse.follow的区别是:前者返回多个请求实例的iterable,而后者返回一个请求 实例。

通过设置 DUPEFILTER_CLASS,scrapy可以过滤掉已经访问过的URL,避免了重复请求。

四、使用蜘蛛参数

import scrapy
class QuotesSpider(scrapy.Spider):
    name = "quotes"
    def start_requests(self):
        url = 'http://quotes.toscrape.com/'
        tag = getattr(self, 'tag', None)
        if tag is not None:
            url = url + 'tag/' + tag
        yield scrapy.Request(url, self.parse)
    def parse(self, response):
        for quote in response.css('div.quote'):
            yield {
                'text': quote.css('span.text::text').get(),
                'author': quote.css('small.author::text').get(),
            }
        next_page = response.css('li.next a::attr(href)').get()
        if next_page is not None:
            yield response.follow(next_page, self.parse)

运行命令行

scrapy crawl quotes -O quotes-humor.json -a tag=humor

通过-a传递的参数,被蜘蛛的 __init__ 方法赋值为蜘蛛的属性。在本例中,通过getattr()获取该参数并使用。

五、CSS选择器与XPath

scrapy shell是一个交互式shell,可以用来快速调试scrape代码,特别是测试数据提取代码(CSS选择器与XPath)。打开命令如下:

scrapy shell "http://quotes.toscrape.com/page/1/"

网页源码:

<head>
    <meta charset="UTF-8">
    <title>Quotes to Scrape</title>
    <link rel="stylesheet" href="/static/bootstrap.min.css">
    <link rel="stylesheet" href="/static/main.css">
</head>

CSS选择器提取代码

//获取符合的数据的列表
>>>response.css('title::text').getall()
//获取第一个符合的数据,没有数据返回None
>>>response.css('title::text').get()
//获取第一个符合的数据,没有数据会引发IndexError
>>>response.css('title::text')[0].get()
//css选择器选择出来后进行正则匹配
>>>response.css('title::text').re(r'Quotes.*')

XPath提取代码

>>>response.xpath('//title')
[<Selector xpath='//title' data='<title>Quotes to Scrape</title>'>]
>>>response.xpath('//title/text()').get()
'Quotes to Scrape'

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/18948.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Deformable Attention学习笔记

Deformable Attention学习笔记 Vision Transformer with Deformable Attention Abstract Transformer 最近在各种视觉任务中表现出卓越的表现。大的(有时甚至是全局的)接受域使Transformer模型比CNN模型具有更高的表示能力。然而&#xff0c;单纯扩大接受野也会引起一些问题…

Linux【进程间通信】

目录 一、什么是进程间通信 管道 管道的原理 匿名管道 1.简单写一个管道 2.总结管道的特点&#xff0c;理解以前的管道 3.扩展 如何写一个进程池&#xff1f; 创建Makefile文件 创建我们的任务头文件Task.cpp 创建我们的主程序文件 一、什么是进程间通信 进程的运…

java项目-第149期ssm师生交流平台_java毕业设计_计算机毕业设计

java项目-第149期ssm师生交流平台-java毕业设计_计算机毕业设计 【源码请到资源专栏下载】 今天分享的项目是《ssm师生交流平台》 该项目分为3个角色&#xff0c;管理员、学生和老师。 学生可以浏览前台查看教学资源、申请做作业、论坛信息、新闻资讯等信息查看。 同时可以跳转…

[MQ] 延迟队列/延迟插件下载

✨✨个人主页:沫洺的主页 &#x1f4da;&#x1f4da;系列专栏: &#x1f4d6; JavaWeb专栏&#x1f4d6; JavaSE专栏 &#x1f4d6; Java基础专栏&#x1f4d6;vue3专栏 &#x1f4d6;MyBatis专栏&#x1f4d6;Spring专栏&#x1f4d6;SpringMVC专栏&#x1f4d6;SpringBoot专…

Linux基本指令3——文件操作

Linux内核&#xff1a;Centos 7.6 64位 find指令 按文件名查找文件的用法&#xff1a;find [路径] -name [文件名] 作用&#xff1a;可以查找目标文件 找到后用nano&#xff0c;通过绝对路径打开目标文件。目前只需要知道这种程度就行了。 grep指令 语法&#xff1a;gre…

浅谈非线性回归(non-linear regression)

文章目录浅谈非线性回归&#xff08;non-linear regression&#xff09;引言最小二乘多项式拟合非线性拟合Gauss–NewtonGauss–NewtonGauss–Newton算法[1]Levenberg–MarquardtLevenberg–MarquardtLevenberg–Marquardt算法[2]Quasi−NewtonQuasi-NewtonQuasi−Newton方法&a…

这样做框架结构图,让你的PPT更有创意!

已剪辑自: https://zhuanlan.zhihu.com/p/58834710 嗨&#xff0c;各位木友们好呀&#xff0c;我是小木。 昨天&#xff0c;有个跟我一样鸟人的鸟人让我帮忙做个框架结构图&#xff1a; 可惜当时我不在办公室&#xff0c;不然我真的一分钟就能把图做给他… ▼ 在文本框里输入…

RabbitMQ_交换机

简单理解交换机在RabbitMQ中扮演的角色 交换机在RabbitMQ中扮演消息系统中枢&#xff0c;将从生产者处收集的消息转发至对应的消息队列处&#xff0c;等待消费者消费 提前说明交换机 与 routing key 与 消息队列的关系 channel.queueBind(queueName, exchangeName, routingKey)…

git4:git整合IDEA和国内代码托管中心码云(自建代码托管平台)

1.配置忽略文件 IDE会生成.idea等无关项目实际功能的文件忽略这些文件配置.ignore 然后再讲此配置文件导入.gitconfig文件中idea中导入git程序 2.测试IDEA vcs 直接项目中 git add commit即可切换版本&#xff08;提交第二版&#xff0c;修改会变成蓝色&#xff0c;然后提交…

血泪史!外包如何找到靠谱的兼职程序员?

好哥们公司上半年的重点项目&#xff0c;黄了。 公司是做线下项目起家的&#xff0c;受到各种不可抗力因素影响改为线上举办。这次的转型老板很看重&#xff0c;但由于整个公司都没有擅长这块的技术开发&#xff0c;于是托朋友找了个外包团队完成。 几十个W花进去&#xff0c;做…

进销存记账软件十大品牌合集,看看哪一款适合你

随着管理成本的提高&#xff0c;加上信息技术的发展&#xff0c;各行各业都要求应用专业的技术软件来提高管理效率&#xff0c;中小商户也不例外。 过往的手工记账已经满足不了需求&#xff0c;进销存记账软件应运而生。 进销存记账软件是时代的产物&#xff0c;也是中小商户…

带你Java入门(Java系列1)

目录 前言&#xff1a; 1.什么是Java 2.Java的语言特点 3.初识Java的main方法 4.注释 5.标识符 6.关键字 7.1基本数据类型 7.2引用数据类型 8.变量 8.1.整形变量 8.2.长整形变量 8.3浮点型变量 8.3.1单精度浮点型 8.3.2双精度浮点型 8.4字符型变量 8.5布尔型…

【计算机网络:自顶向下方法】(二)应用层

tm 【计算机网络&#xff1a;自顶向下方法】(二)应用层 文章目录应用层如何创建一个新的网络应用?2.1 应用层原理网络应用的体系结构对等模式(P2P:Peer To Peer)混合体&#xff1a;客户-服务器和对等体系结构进程通信分布式进程通信需要解决的问题问题1&#xff1a;进程…

CorelDRAW2023全新版功能及下载安装教程

CorelDraw2023是一款优秀的图形工具。有了它&#xff0c;不太专业的客户也可以做直观和简短的组成&#xff0c;由于其平滑和简单的用户界面。你可以一起做很多编辑工作。有了这个巨大的工具&#xff0c;你可以对你的图像、网站、商标和其他许多东西产生美丽而令人印象深刻的效果…

DJYOS驱动开发系列一:基于DJYOS的UART驱动编写指导手册

1.概述 DJYOS设计通用的串口驱动模型&#xff0c;在此模型的基础上&#xff0c;移植到不同硬件平台时&#xff0c;只需提供若干硬件操作函数&#xff0c;即可完成串口驱动开发&#xff0c;使开发工作变得简单而快速执行效率高。 DJYOS源代码都有特定的存放位置&#xff0c; 建…

DJYGUI系列文章五:GK显示器接口

1 GK显示器接口概述 显示器是图形显示的终端&#xff0c;图形的所有操作都会直接或间接的体现在显示器上面。DJYGUI支持多显示器、虚显示器和镜像显示器的功能。应用程序在调用API函数绘图前&#xff0c;需安装显示器&#xff0c;按照GK显示器标接口实现驱动函数。 GK的底层硬件…

DCS系统组态设计实验

太原理工大学控制仪表实验之DCS系统组态设计实验 DCS系统组态设计一.实验内容1.根据自己的理解&#xff0c;复述实验整体流程&#xff0c;并画出实验整体流程图。2.根据视频&#xff0c;写出DCS 信号通道接线关系表。即主控站DCS模块名称&#xff0c;模块型号&#xff0c;I/O模…

跟艾文学编程《Python基础》(5)Python的文件操作

作者&#xff1a; 艾文&#xff0c;计算机硕士学位&#xff0c;企业内训讲师和金牌面试官&#xff0c;公司资深算法专家&#xff0c;现就职BAT一线大厂。邮箱&#xff1a; 1121025745qq.com博客&#xff1a;https://wenjie.blog.csdn.net/内容&#xff1a;跟艾文学编程《Python…

linux网络编程epoll内核实现代码分析

1、linux内核epoll相关数据结构 1.1、epoll相关数据结构类图 1.2、关键数据结构说明 socket_wq结构体包含一个__wait_queue_head成员&#xff0c;__wait_queue_head用于连接wait_queue_t链表&#xff0c;对于epoll而言就是连接eppoll_entry&#xff1b; eppoll_entry包含一个e…

第七届信息类研究生学术论坛参赛有感

因为疫情不仅感叹时光飞逝&#xff0c;上了大半年的网课再次回到校园已经有师弟师妹了。今年的研究生学术论坛更卷了&#xff0c;入围了88项作品。这次科研作品征集研究生在学期间信息类相关研究成果&#xff0c;鼓励实物参展&#xff0c;包括软件系统、硬件系统等&#xff0c;…