前言

如何优雅的获取同一个网站上下一次爬取的链接并放到生成一个 Scrapy Response 呢?

样例

from urllib import parse

import scrapy

class SitoiSpider(scrapy.Spider):
name = "sitoi" start_urls = [
'https://sitoi.cn',
] def parse(self, response):
href_list = response.xpath("//div[@class='card']/a/@href").extract()
for href in href_list:
url = parse.urljoin(response.url, href)
yield scrapy.Request(url=url, callback=self.parse_next) def parse_next(self, response):
print(response.url)

方式一:使用 urllib 库来拼接 URL

这个方式是通过 urllib 库来对下一个 url 进行补全成完整的 url,再使用 scrapy.Request 的方式进行下一个页面的爬取。

优点

  1. 在处理每一个 href 的时候可以添加一些自定义的内容(例如记录一下当前第几页了等等)

缺点

  1. 需要引入其他的库
def parse(self, response):
href_list = response.xpath("//div[@class='card']/a/@href").extract()
for href in href_list:
url = parse.urljoin(response.url, href)
yield scrapy.Request(url=url, callback=self.parse_next)

方式二:使用 response 自带的 urljoin

这个方式是通过 Scrapy response 自带的 urljoin 对下一个 url 进行补全成完整的 url,再使用 scrapy.Request 的方式进行下一个页面的爬取。(和方式一基本相同)

优点

  1. 不再需要在 spider 文件中引入多的第三方库。
def parse(self, response):
href_list = response.xpath("//div[@class='card']/a/@href").extract()
for href in href_list:
url = response.urljoin(href)
yield scrapy.Request(url=url, callback=self.parse_next)

方式三:使用 response 自带的 follow

这个方式是通过 Scrapy response 自带的 follow 进行下一个页面的爬取。

优点

  1. 不再需要在 spider 文件中引入多的第三方库。
  2. 不需要写 extract() 来提取 href 字符串,只需要传入 href 这个 Selector(可选)
  3. 不需要写 url 拼接
  4. xpath 只需要编写到 a 标签即可,可以省略掉 @href,即不需要获取 href 的 Selector,直接传递 a 的 Selector(可选)
def parse(self, response):
href_list = response.xpath("//div[@class='card']/a/@href").extract()
for href in href_list:
yield response.follow(url=href, callback=self.parse_next)

变种一

  1. 不写 extract() 来提取 href 字符串,传入 href 这个 Selector
def parse(self, response):
href_list = response.xpath("//div[@class='card']/a/@href")
for href in href_list:
yield response.follow(url=href, callback=self.parse_next)

变种二

  1. 不写 extract() 来提取 href 字符串,传入 href 这个 Selector
  2. xpath 不写 @href,直接传递 a 的 Selector
def parse(self, response):
href_list = response.xpath("//div[@class='card']/a/")
for href in href_list:
yield response.follow(url=href, callback=self.parse_next)

方式四:使用 response 自带的 follow_all

这个方式是通过 Scrapy response 自带的 follow_all 进行下一个页面的爬取。

优点

  1. 不再需要在 spider 文件中引入多的第三方库。
  2. 不需要写 extract() 来提取 href 字符串,只需要传入 href 这个 selector(可选)
  3. 不需要写 url 拼接
  4. 只需要编写到 a 标签即可,可以省略掉 @href,即不需要获取 href 的 SelectorList,直接传递 a 的 SelectorList(可选)
  5. 不需要编写遍历,直接把抓到的 url 的 SelectorList 放入即可

缺点

  1. 如果中间还有什么逻辑,就不太适用了(例如记录一下当前第几页了等等)
def parse(self, response):
href_list = response.xpath("//div[@class='card']/a")
yield from response.follow_all(urls=href_list, callback=self.parse_next)

变种

注:前方高能

一行代码搞定。

def parse(self, response):
yield from response.follow_all(xpath="//div[@class='card']/a", callback=self.parse_next)

欢迎访问我的个人博客:https://sitoi.cn

Scrapy 小技巧(一):使用 scrapy 自带的函数(follow & follow_all)优雅的生成下一个请求的更多相关文章

  1. 芝麻HTTP:Scrapy小技巧-MySQL存储

    这两天上班接手,别人留下来的爬虫发现一个很好玩的 SQL脚本拼接. 只要你的Scrapy Field字段名字和 数据库字段的名字 一样.那么恭喜你你就可以拷贝这段SQL拼接脚本.进行MySQL入库处理 ...

  2. 芝麻HTTP: Scrapy小技巧-MySQL存储

    这两天上班接手,别人留下来的爬虫发现一个很好玩的 SQL脚本拼接. 只要你的Scrapy Field字段名字和 数据库字段的名字 一样.那么恭喜你你就可以拷贝这段SQL拼接脚本.进行MySQL入库处理 ...

  3. Scrapy小技巧-MySQL存储, MYSQL拼接

    这两天上班接手,别人留下来的爬虫发现一个很好玩的 SQL脚本拼接. 只要你的Scrapy Field字段名字和 数据库字段的名字 一样.那么恭喜你你就可以拷贝这段SQL拼接脚本.进行MySQL入库处理 ...

  4. 【小技巧】只用css实现带小三角的对话框样式

    一个小小的技巧: 如图所示,这种小三角,不用图片,只用css怎么实现呢? 直接上代码吧: <!DOCTYPE html> <html> <head> <tit ...

  5. Extjs 项目中常用的小技巧,也许你用得着(5)--设置 Ext.data.Store 传参的请求方式

    1.extjs 给怎么给panel设背景色 设置bodyStyle:'background:#ffc;padding:10px;', var resultsPanel = Ext.create('Ex ...

  6. 10个提升MySQL性能的小技巧

    从工作量分析到索引的三条规则,这些专家见解肯定会让您的MySQL服务器尖叫. 在所有的关系数据库中,MySQL已经被证明了完全是一头野兽,只要通知停止运行就绝对不会让你多等一秒钟,使你的应用置于困境之 ...

  7. 模仿也是提高,纯css小技巧实现头部进度条

    刚开始的时候我也觉得不可能,但是就是这么神奇,总有大神给你意想不到的惊喜. 快来感受一下把.(仔细看看头部黄色条的变化) 思考一下啊,怎么出现的那,其实作者使用了一点小技巧,那就是背景色渐变和遮挡产生 ...

  8. Python 中的一些小技巧

    这里是本人收集的一些 Python 小技巧,目前主要是一些实用函数,适合有一定基础的童鞋观看(不会专门介绍使用到的标准库函数).. 一.函数式编程 函数式编程用来处理数据,感觉很方便.(要是再配上管道 ...

  9. 【js】中的小技巧

    本文主要介绍一些JS中用到的小技巧 1. 类型强制转换   1.1 string强制转换为数字 可以用*1来转化为数字(实际上是调用.valueOf方法) 然后使用Number.isNaN来判断是否为 ...

随机推荐

  1. 下载Android代码

    1.由于墙,无法下载android源码,但是又不想利用清华源repo下载整个工程,只下载个别仓库 解决办法: 2.下载frameworks/base: git clone https://androi ...

  2. 将mat文件中的数据按要求保存到txt文档中(批处理)

    之前有个老朋友,让帮忙将一个mat中的数据重新保存到txt中,由于数据比较多需要用到批处理,之前弄过很多次,但每次一到要用的时候总是忘记怎么写了,现在记录一下,免得后面老是需要上网搜.这里先说一个比较 ...

  3. 我的第一篇博客-学习书写markdown

    Markdown学习(标题:井号+空格+标题名字 回车 ) 标题: 二级标题## 空格+名字 三级标题### 空格+名字 四级标题#### 空格+名字 五级标题##### 空格+名字 六级标题#### ...

  4. hdu6470 Count 矩阵快速幂

    hdu6470 Count #include <bits/stdc++.h> using namespace std; typedef long long ll; , mod = ; st ...

  5. 07 返回多个页面web框架

    07 返回多个页面web框架 服务器server端python程序(不同页面版本): import socket server=socket.socket() server.bind(("1 ...

  6. poj2699 转化为可行性判定问题+二分枚举+最大流

    The Maximum Number of Strong Kings Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2302 ...

  7. Nginx301重定向

    1)301重定向,把blog.moonsbird.com和moonsbirl.com合并,并把之前的域名也一并合并. 有两种实现方法,第一种方法是判断nginx核心变量host(老版本是http_ho ...

  8. PHP文件上传案例和函数

    $_FILES参数详解: $_FILES["file"]["name"] – 被上传文件的名称 $_FILES["file"][" ...

  9. C#中的List基础用法汇总

    List类是ArrayList类的泛型等效类,该类使用大小可按需动态增加的数组实现IList泛型接口. 泛型的好处:它为使用c#语言编写面向对象程序增加了极大的效力和灵活性.不会强行对值类型进行装箱和 ...

  10. SpringBoot外部化配置使用Plus版

    本文如有任何纰漏.错误,请不吝指正! PS: 之前写过一篇关于SpringBoo中使用配置文件的一些姿势,不过嘛,有句话(我)说的好:曾见小桥流水,未睹观音坐莲!所以再写一篇增强版,以便记录. 序言 ...