『scrapy爬虫』03. 爬取多个页面(详细注释步骤)

目录

    • 1. 分析网页试着拿到多个页面的url
    • 2. 抓取250个电影
    • 3. start_requests的使用
    • 4. 代码规范
      • 导库的优化
      • 关于重写
      • 最终修改后的代码
    • 总结


欢迎关注 『scrapy爬虫』 专栏,持续更新中
欢迎关注 『scrapy爬虫』 专栏,持续更新中

1. 分析网页试着拿到多个页面的url

看到了一个个a标签对应的几页的页码url
在这里插入图片描述
这是1页到3页,因为是top250,总共10页.每一页就是25个,也对应着url中的参数0,25,50````````

https://movie.douban.com/top250?start=0&filter=
https://movie.douban.com/top250?start=25&filter=
https://movie.douban.com/top250?start=25&filter=

我们的douban.py

import scrapy
from scrapy import Selectorfrom myscrapy.items import MovieItemclass DoubanSpider(scrapy.Spider):name = "douban"allowed_domains = ["movie.douban.com"]# 限制或允许访问的域名列表start_urls = ["https://movie.douban.com/top250"] # 起始urldef parse(self, response):myselector=Selector(text=response.text)# 拿到了所有的li,也就是所有的电影,每一个li代表一个电影,list_items是由250个电影li组成的listlist_items=myselector.css("#content > div > div.article > ol > li")for list_item in list_items:movie_item=MovieItem()#新建类的对象# 电影标题的 Selector# content > div > div.article > ol > li:nth-child(1) > div > div.info > div.hd > a > span:nth-child(1)movie_item['title']=list_item.css("span.title::text").extract_first() # extract_first()从选择器中提取第一个匹配的数据。# 电影评分# content > div > div.article > ol > li:nth-child(1) > div > div.info > div.bd > div > span.rating_nummovie_item['score']=list_item.css("span.rating_num::text").extract_first()  # extract_first()从选择器中提取第一个匹配的数据。# # 电影影评# content > div > div.article > ol > li:nth-child(1) > div > div.info > div.bd > p.quote > spanmovie_item['quato']=list_item.css("span.inq::text").extract_first()  # extract_first()从选择器中提取第一个匹配的数据。yield movie_item#把整理得到的数据给管道# 单个页面selector# content > div > div.article > div.paginator > a:nth-child(3)# ::attr(href)表示选取元素的href属性。使用.getall()方法可以获取匹配到的所有元素的href属性值,并将其存储在一个列表中。hrefs_list=myselector.css('div.paginator > a::attr(href)')for href in hrefs_list:url=response.urljoin(href.extract())print(url)

cmd运行,可以看到获取了url

scrapy crawl douban

在这里插入图片描述


2. 抓取250个电影

这里要用到scrapy中的request库,注意不是我们之前的requests这一个s的区别很大,不要导错包了.

我们之前不是定义过一个MovieItem类吗?这个request是scrapy内部定义好的,我们在这里传入的url都会和我们前面的start_urls = ["https://movie.douban.com/top250"] # 起始url 一样用于爬虫.

import scrapy
from scrapy import Selector,Request
from myscrapy.items import MovieItemclass DoubanSpider(scrapy.Spider):name = "douban"allowed_domains = ["movie.douban.com"]# 限制或允许访问的域名列表start_urls = ["https://movie.douban.com/top250"] # 起始urldef parse(self, response):myselector=Selector(text=response.text)# 拿到了所有的li,也就是所有的电影,每一个li代表一个电影,list_items是由250个电影li组成的listlist_items=myselector.css("#content > div > div.article > ol > li")for list_item in list_items:movie_item=MovieItem()#新建类的对象# 电影标题的 Selector# content > div > div.article > ol > li:nth-child(1) > div > div.info > div.hd > a > span:nth-child(1)movie_item['title']=list_item.css("span.title::text").extract_first() # extract_first()从选择器中提取第一个匹配的数据。# 电影评分# content > div > div.article > ol > li:nth-child(1) > div > div.info > div.bd > div > span.rating_nummovie_item['score']=list_item.css("span.rating_num::text").extract_first()  # extract_first()从选择器中提取第一个匹配的数据。# # 电影影评# content > div > div.article > ol > li:nth-child(1) > div > div.info > div.bd > p.quote > spanmovie_item['quato']=list_item.css("span.inq::text").extract_first()  # extract_first()从选择器中提取第一个匹配的数据。yield movie_item#把整理得到的数据给管道# 单个页面selector# content > div > div.article > div.paginator > a:nth-child(3)# ::attr(href)表示选取元素的href属性。使用.getall()方法可以获取匹配到的所有元素的href属性值,并将其存储在一个列表中。hrefs_list=myselector.css('div.paginator > a::attr(href)')for href in hrefs_list:url=response.urljoin(href.extract())# print(url)# 将 Request 对象加入到爬虫的请求队列中,以便发送请求,相当于对每个页面执行抓取数据yield Request(url=url) #注意这个Request是来自scrapy的.   from scrapy import Selector,Request

cmd运行

scrapy crawl douban  -o douban250.csv

在这里插入图片描述


3. start_requests的使用

修复一个bug(为什么250条数据变多了)?
我们的起始页面start_urls = ["https://movie.douban.com/top250"] # 起始url
但是我们知道,页面的规则,因为是第一页比较特殊,省略了参数0,实际上第一页的url应该是https://movie.douban.com/top250?start=0&filter=,这导致我们重复2次爬取了第一页的数据,出现了2次肖申克的救赎
在这里插入图片描述
解决方案1,直接修改起始页面

start_urls = ["https://movie.douban.com/top250"] # 起始url
改为
start_urls = ["https://movie.douban.com/top250?start=0&filter="] # 起始url

优雅方案2,start_requests一开始就设置要解析的url,不爬取页面url,告诉爬虫要爬的页面有哪些

import scrapy
from scrapy import Selector,Request
from myscrapy.items import MovieItemclass DoubanSpider(scrapy.Spider):name = "douban"allowed_domains = ["movie.douban.com"]# 限制或允许访问的域名列表start_urls = ["https://movie.douban.com/top250"] # 起始urldef start_requests(self) :for page in range(10): #10页yield Request(url=f'https://movie.douban.com/top250?start={page*25}&filter=')def parse(self, response):myselector=Selector(text=response.text)# 拿到了所有的li,也就是所有的电影,每一个li代表一个电影,list_items是由250个电影li组成的listlist_items=myselector.css("#content > div > div.article > ol > li")for list_item in list_items:movie_item=MovieItem()#新建类的对象# 电影标题的 Selector# content > div > div.article > ol > li:nth-child(1) > div > div.info > div.hd > a > span:nth-child(1)movie_item['title']=list_item.css("span.title::text").extract_first() # extract_first()从选择器中提取第一个匹配的数据。# 电影评分# content > div > div.article > ol > li:nth-child(1) > div > div.info > div.bd > div > span.rating_nummovie_item['score']=list_item.css("span.rating_num::text").extract_first()  # extract_first()从选择器中提取第一个匹配的数据。# # 电影影评# content > div > div.article > ol > li:nth-child(1) > div > div.info > div.bd > p.quote > spanmovie_item['quato']=list_item.css("span.inq::text").extract_first()  # extract_first()从选择器中提取第一个匹配的数据。yield movie_item#把整理得到的数据给管道# # 单个页面selector# # content > div > div.article > div.paginator > a:nth-child(3)# # ::attr(href)表示选取元素的href属性。使用.getall()方法可以获取匹配到的所有元素的href属性值,并将其存储在一个列表中。# hrefs_list=myselector.css('div.paginator > a::attr(href)')# for href in hrefs_list:#     url=response.urljoin(href.extract())#     # print(url)#     # 将 Request 对象加入到爬虫的请求队列中,以便发送请求,相当于对每个页面执行抓取数据#     yield Request(url=url) #注意这个Request是来自scrapy的.   from scrapy import Selector,Request

cmd运行

scrapy crawl douban  -o douban250_true.csv

在这里插入图片描述


4. 代码规范

导库的优化

在优化 Python 代码的导入语句时,通常会按照一定的规则和顺序进行排序和分组。这些规则和顺序有助于提高代码的可读性和维护性。以下是一般情况下推荐的导入规则和顺序:

  • 标准库导入:首先导入Python标准库中的模块,每个导入语句占一行。
python
import os
import sys
  • 第三方库导入:接着导入第三方库或框架的模块,每个导入语句占一行。
python
import requests
import pandas as pd

本地应用/模块导入:最后导入项目中的自定义模块或应用程序模块。

python
from myapp import utils
from myapp.models import User
  • 空行分隔:在不同类型的导入之间加入空行,以提高可读性。

  • 按字母顺序排序:可以按照字母顺序对每个导入组进行排序,或者使用工具自动排序。

  • 避免通配符导入:尽量避免使用 from module import * 的方式,应该明确导入需要的内容。

  • 别名处理:合理使用别名来简化长模块名,但不要过度缩写或使用难以理解的别名。用一些约定俗成的别名.

import pandas as pd

可以使用pycharm的快捷整理你的导包书写规范
在这里插入图片描述

关于重写

可以看到警告.
在这里插入图片描述

Signature of method 'DoubanSpider.parse()' does not match signature of the base method in class 'Spider'

这是因为我们的parse继承的DoubanSpider类的scrapy.Spider,我们按住ctrl点击scrapy.Spider前往观察这个被重写的方法,从图中可以看到这几个def都是重写这个spide的方法
在这里插入图片描述

class DoubanSpider(scrapy.Spider):def parse(self, response):

可以看到被重写的方法原型
在这里插入图片描述
统一格式

改为下面代码即可消除警告
def parse(self,response, **kwargs):

最终修改后的代码

import scrapy
from scrapy import Selector,Request
from myscrapy.items import MovieItemclass DoubanSpider(scrapy.Spider):name = "douban"allowed_domains = ["movie.douban.com"]# 限制或允许访问的域名列表start_urls = ["https://movie.douban.com/top250"] # 起始urldef start_requests(self) :for page in range(10): #10页yield Request(url=f'https://movie.douban.com/top250?start={page*25}&filter=')def parse(self,response, **kwargs):myselector=Selector(text=response.text)# 拿到了所有的li,也就是所有的电影,每一个li代表一个电影,list_items是由250个电影li组成的listlist_items=myselector.css("#content > div > div.article > ol > li")for list_item in list_items:movie_item=MovieItem()#新建类的对象# 电影标题的 Selector# content > div > div.article > ol > li:nth-child(1) > div > div.info > div.hd > a > span:nth-child(1)movie_item['title']=list_item.css("span.title::text").extract_first() # extract_first()从选择器中提取第一个匹配的数据。# 电影评分# content > div > div.article > ol > li:nth-child(1) > div > div.info > div.bd > div > span.rating_nummovie_item['score']=list_item.css("span.rating_num::text").extract_first()  # extract_first()从选择器中提取第一个匹配的数据。# # 电影影评# content > div > div.article > ol > li:nth-child(1) > div > div.info > div.bd > p.quote > spanmovie_item['quato']=list_item.css("span.inq::text").extract_first()  # extract_first()从选择器中提取第一个匹配的数据。yield movie_item#把整理得到的数据给管道# # 单个页面selector# # content > div > div.article > div.paginator > a:nth-child(3)# # ::attr(href)表示选取元素的href属性。使用.getall()方法可以获取匹配到的所有元素的href属性值,并将其存储在一个列表中。# hrefs_list=myselector.css('div.paginator > a::attr(href)')# for href in hrefs_list:#     url=response.urljoin(href.extract())#     # print(url)#     # 将 Request 对象加入到爬虫的请求队列中,以便发送请求,相当于对每个页面执行抓取数据#     yield Request(url=url) #注意这个Request是来自scrapy的.   from scrapy import Selector,Request

总结

大家喜欢的话,给个👍,点个关注!给大家分享更多计算机专业学生的求学之路!

版权声明:

发现你走远了@mzh原创作品,转载必须标注原文链接

Copyright 2024 mzh

Crated:2024-3-1

欢迎关注 『scrapy爬虫』 专栏,持续更新中
欢迎关注 『scrapy爬虫』 专栏,持续更新中
『未完待续』


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

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

相关文章

关于tcp协议

目录 前言: 一、TCP协议的基本概念: 二、TCP协议的主要特点: 2.1面向连接: 2.2可靠传输: 2.3基于字节流: 三、TCP连接的建立与终止: 3.1连接建立: 3.1.1SYN: 3…

MyBatis3源码深度解析(十一)MyBatis常用工具类(四)ObjectFactoryProxyFactory

文章目录 前言3.6 ObjectFactory3.7 ProxyFactory3.8 小结 前言 本节研究ObjectFactory和ProxyFactory的基本用法,因为它们在MyBatis的源码中比较常见。这里不深究ObjectFactory和ProxyFactory的源码,而是放到后续章节再展开。 3.6 ObjectFactory Obj…

朴素贝叶斯 | 多分类问题

目录 一. 贝叶斯公式的推导二. 朴素贝叶斯1. 离散的朴素贝叶斯朴素贝叶斯导入示例 离散的朴素贝叶斯训练 2. 连续的朴素贝叶斯3. 伯努利朴素贝叶斯4. 多项式朴素贝叶斯4.1 Laplace平滑4.2 Lidstone平滑 三. 概率图模型1. 贝叶斯网络(Bayesian Network)1.1 全连接贝叶斯网络1.2 …

中国城市统计年鉴、中国县域统计年鉴、中国财政统计年鉴、中国税务统计年鉴、中国科技统计年鉴、中国卫生统计年鉴​

统计年鉴是指以统计图表和分析说明为主,通过高度密集的统计数据来全面、系统、连续地记录年度经济、社会等各方面发展情况的大型工具书来获取统计数据资料。 统计年鉴是进行各项经济、社会研究的必要前提。而借助于统计年鉴,则是研究者常用的途径。目前国…

redis在微服务领域的贡献,字节跳动只面试两轮

dubbo.registry.addressredis://127.0.0.1:6379 注册上来的数据是这样,类型是hash /dubbo/ s e r v i c e / {service}/ service/{category} 如 /dubbo/com.newboo.sample.api.DemoService/consumers /dubbo/com.newboo.sample.api.DemoService/providers has…

Prompt Learning:人工智能的新篇章

开篇:AI的进化之旅 想象一下,你正在和一位智能助手对话,它不仅理解你的问题,还能提出引导性的问题帮助你更深入地思考。这正是prompt learning的魔力所在——它让机器学习模型变得更加智能和互动。在这篇博客中,我们将…

安装MySQL8.0及以上版本操作步骤

关于mysql安装过程中命令mysqld --initialize --console出错的解答 C:\mysql-8.3.0-winx64\bin>mysqld --initialize --usermysql --console 2024-03-12T11:21:23.201387Z 0 [System] [MY-015017] [Server] MySQL Server Initialization - start. 2024-03-12T11:21:23.2068…

【05】消失的数字

hellohello~这里是土土数据结构学习笔记🥳🥳 💥个人主页:大耳朵土土垚的博客 💥所属专栏:C语言函数实现 感谢大家的观看与支持🌹🌹🌹 有问题可以写在评论区或者私信我哦…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Text)

显示一段文本的组件。 说明: 该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 子组件 可以包含Span和ImageSpan子组件。 接口 Text(content?: string | Resource, value?: TextOptions) 从API versi…

论文阅读——ViTAE

ViTAE: Vision Transformer Advanced by Exploring Intrinsic Inductive Bias ViTAE旨在将细胞神经网络中固有的IB引入视觉转换器。如图2所示,ViTAE由两种类型的细胞组成,即RC和NC。RC负责将多尺度上下文和局部信息嵌入到令牌中,NC用于进一步…

AUTOSAR软件配置(3):MCAL下载安装

前言 所有的NXP软件的下载安装都是需要自己在官网去注册账号的 中文的NXP官方网址:恩智浦半导体官方网站 | NXP 半导体 注:本文指导安装教程将以S32K144平台为例展开。 下载 找到下载入口的指引 然后在左侧的导航栏找到AUTOSAR 然后选择4.2版本 在…

java-集合工具类Collections

我们在使用它的时候记得导包 常见API 我们就简单看看第一第二个方法,代码如下,其余的知道用就行

信息系统项目管理师--沟通管理

IT 项⽬成功有关的最重要的四个因素是:主管层的⽀持、⽤户参与、有经验的项⽬经理和清晰的业务⽬标 项⽬沟通管理是确保及时、正确地产⽣、收集、分发、存储和最终处理项⽬信息所需的过程 项⽬沟通管理由两部分组成:⼀是制定策略,确保沟通对…

leetcode一天一题-第1天

为了增加自己的代码实战能力,希望通过刷leetcode的题目,不断提高自己,增加对代码的理解,同时开拓自己的思维方面。 题目名称:两数之和 题目编号:1 题目介绍: 给定一个整数数组 nums 和一个整数…

中介者模式(Mediator Pattern)

中介者模式 说明 中介者模式(Mediator Pattern)属于行为型模式,又称为调解者模式或调停者模式。用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使其耦合松散,而且可以独立…

【AI大模型应用开发】【LangChain系列】9. 实用技巧:大模型的流式输出在 OpenAI 和 LangChain 中的使用

大家好,我是同学小张,日常分享AI知识和实战案例欢迎 点赞 关注 👏,持续学习,持续干货输出。v: jasper_8017 一起交流💬,一起进步💪。微信公众号也可搜【同学小张】 🙏 本…

Python使用openpyxl库或pandas库创建.xlsx格式的Excel文件,并向文件不同的sheet按行或按列写入内容

import openpyxl# 创建-一个Workbook对象 wb openpyxl.Workbook()# 创建多个工作表 sheet1 wb.active sheet1.title "s1"sheet2 wb.create_sheet("s2")# 在不同的工作表中写入数据 sheet1["A1"] Data for Sheet1 sheet1["A2"] D…

数学问题难解?新研究提出MathScale方法,让AI更懂数学推理

引言:数学问题解决中的语言模型挑战 数学问题解决是一个复杂的认知过程,它要求参与者不仅要掌握数学知识,还要能够进行多步骤的逻辑推理。近年来,大语言模型(LLMs)在解决问题方面展现出了显著的能力&#…

18. 查看帖子详情

文章目录 一、建立路由二、开发GetPostDetailHandler三、编写logic四、编写dao层五、编译测试运行 一、建立路由 router/route.go v1.GET("/post/:id", controller.GetPostDetailHandler)二、开发GetPostDetailHandler controller/post.go func GetPostDetailHand…

java数据结构与算法刷题-----LeetCode90. 子集 II

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846 文章目录 解题思路:时间复杂度O( n 2 ∗ n n^2*n n2∗n),空间复杂度O(n) 7…