excel翻页不连续_简易数据分析(八): Web Scraper 抓取详情页、利用 Link 选择器翻页...

e62ad36da0f15c83051faf32b100eff0.png

不知不觉,web scraper 系列教程我已经写了 10 篇了,这 10 篇内容,基本上覆盖了 Web Scraper 大部分功能。今天的内容算这个系列的最后一篇文章了,下一章节我会开一个新坑,说说如何利用 Excel 对收集到的数据做一些格式化的处理和分析。

Web Scraper 教程的全盘总结我放在下一篇文章,今天先开始我们的实战教程。

在前面的课程里,我们抓取的数据都是在同一个层级下的内容,探讨的问题主要是如何应对市面上的各种分页类型,但对于详情页内容数据如何抓取,却一直没有介绍。

比如说我们想抓取 b 站的动画区 TOP 排行榜的数据:

https://www.bilibili.com/ranking/all/1/0/3

按之前的抓取逻辑,我们是把这个榜单上和作品有关的数据抓取一遍,比如说下图里的排名、作品名字、播放量、弹幕数和作者名。

427cd8916c681c0a7e3ad9f046ad25d7.png

经常逛 B 站的小伙伴也知道,UP 主经常暗示观看视频小伙伴三连操作(点赞+投币+收藏),由此可见,这 3 个数据对视频的排名有一定的影响力,所以这些数据对我们来说也有一定的参考价值。

25e977c0e28b5db2e055877ec9b8ec17.gif

但遗憾的是,在这个排名列表里,并没有相关数据。这几个数据在视频详情页里,需要我们点击链接进去才能看到:

43aaacf84b3b5ca262a95bb6639a5455.gif

今天的教程内容,就是教你如何利用 Web Scraper,在抓取一级页面(列表页)的同时,抓取二级页面(详情页)的内容。

1.创建 SiteMap

首先我们找到要抓取的数据的位置,关键路径我都在下图的红框里标出来了,大家可以对照一下:

9acaf437a137c6d9acab8a2a38ffec51.png

然后创建一个相关的 SiteMap,这里我取了个 bilibili_rank 的名字:

735a8636f203ae9abe5fb61b96ec5b88.png

2.创建容器的 selector

设置之前我们先观察一下,发现这个网页的排行榜数据是 100 条数据一次性加载完的,没有分页的必要,所以这里的 Type 类型选为 Element 就行。

其他的参数都比较简单,就不细说了(不太懂的可以看我之前的基础教程)这里截个图大家可以做个参考:

22760ee7b9b5d0764e364099b8816bf7.png

3.创建列表页子选择器

这次子选择器要抓取的内容如下,也都比较简单,截个图大家可以参考一下:

  1. 排名(num)

  2. 作品标题(title)

  3. 播放量(play_amount)

  4. 弹幕量(danmu_count)

  5. 作者:(author)

427cd8916c681c0a7e3ad9f046ad25d7.png

2a4903e6bd69c4455c98a93969c6c885.png

如果做到这一步,其实已经可以抓到所有已知的列表数据了,但本文的重点是:如何抓取二级页面(详情页)的三连数据?

跟着做了这么多爬虫,可能你已经发现了,Web Scraper 本质是模拟人类的操作以达到抓取数据的目的

那么我们正常查看二级页面(详情页)是怎么操作的呢?其实就是点击标题链接跳转

b0d87ebdc1d87db258bc3d5139f1771a.gif

Web Scraper 为我们提供了点击链接跳转的功能,那就是 Type 为 Link 的选择器。

感觉有些抽象?我们对照例子来理解一下。

首先在这个案例里,我们获取了标题的文字,这时的选择器类型为 Text:

d30c197f624bfab8ded5f59ce6a2ae5a.png

当我们要抓取链接时,就要再创建一个选择器,选的元素是一样的,但是 Type 类型为 Link

122f2d6e64415fd88c94c22ec0f3b454.png

创建成功后,我们点击这个 Link 类型的选择器,进入他的内部,再创建相关的选择器,下面我录了个动图,注意看我鼠标强调的导航路由部分,可以很清晰的看出这几个选择器的层级关系:

4ffa446367882c1a70f21cc9aa17c936.gif

4.创建详情页子选择器

当你点击链接后就会发现,浏览器会在一个新的 Tab 页打开详情页,但是 Web Scraper 的选择窗口开在列表页,无法跨页面选择想要的数据。

处理这个问题也很简单,你可以复制详情页的链接,拷贝到列表页所在的 Tab 页里,然后回车重新加载,这样就可以在当前页面选择了。

2631db98b92e389c9a26429abbb75a9d.gif

我们在类型为 Link 的选择器内部多创建几个选择器,这里我选择了点赞数、硬币数、收藏数和分享数 4 个数据,这个操作也很简单,这里我就不详细说了。

bae6050a3dde5d32ce3afef52458a5b6.png

所有选择器的结构图如下:

2afa7560c10271ee4bfde3c1a9a241e6.png

我们可以看到 video_detail_link 这个节点包含 4 个二级页面(详情页)的数据,到此为止,我们的子选择器已经全部建立好了。

5.抓取数据

终于到了激动人心的环节了,我们要开始抓取数据了。但是抓取前我们要把等待时间调整得大一些,默认时间是 2000 ms,我这里改成了 5000 ms。

f0beee637e4bb781dbaa1c90894b2b36.png

为什么这么做?看了下图你就明白了:

5cbc72d2c900c6e9a78fd28aecf23438.gif

首先,每次打开二级页面,都是一个全新的页面,这时候浏览器加载网页需要花费时间;

其次,我们可以观察一下要抓取的点赞量等数据,页面刚刚加载的时候,它的值是 「--」,等待一会儿后才会变成数字。

所以,我们直接等待 5000 ms,等页面和数据加载完成后,再统一抓取。

配置好参数后,我们就可以正式抓取并下载了。下图是我抓取数据的一部分,特此证明此方法有用:

7703dcb85f0a85e43dd142dd99242724.png

6.总结

这次的教程可能有些难度,我把我的 SiteMap 分享出来,制作的时候如果遇到难题,可以参考一下我的配置,SiteMap 导入的功能我在第 6 篇教程里详细说明了,大家可以配合食用:

{"_id":"bilibili_rank","startUrl":["https://www.bilibili.com/ranking/all/1/0/3"],"selectors":[{"id":"container","type":"SelectorElement","parentSelectors":["_root"],"selector":"li.rank-item","multiple":true,"delay":0},{"id":"title","type":"SelectorText","parentSelectors":["container"],"selector":"a.title","multiple":false,"regex":"","delay":0},{"id":"author","type":"SelectorText","parentSelectors":["container"],"selector":"a span","multiple":false,"regex":"","delay":0},{"id":"play_amount","type":"SelectorText","parentSelectors":["container"],"selector":".detail > span:nth-of-type(1)","multiple":false,"regex":"","delay":0},{"id":"danmu_amount","type":"SelectorText","parentSelectors":["container"],"selector":"span:nth-of-type(2)","multiple":false,"regex":"","delay":0},{"id":"video_detail_link","type":"SelectorLink","parentSelectors":["container"],"selector":"a.title","multiple":false,"delay":0},{"id":"coin","type":"SelectorText","parentSelectors":["video_detail_link"],"selector":"span.coin","multiple":false,"regex":"","delay":0},{"id":"collect","type":"SelectorText","parentSelectors":["video_detail_link"],"selector":"span.collect","multiple":false,"regex":"","delay":0},{"id":"share","type":"SelectorText","parentSelectors":["video_detail_link"],"selector":"span.share","multiple":false,"regex":"[0-9]+","delay":0},{"id":"num","type":"SelectorText","parentSelectors":["container"],"selector":"div.num","multiple":false,"regex":"","delay":0},{"id":"like","type":"SelectorText","parentSelectors":["video_detail_link"],"selector":".ops span.like","multiple":false,"regex":"","delay":0}]}

当你掌握了二级页面的抓取方式后,三级页面、四级页面也不在话下。因为套路都是一样的:都是先创建 Link 选择器、然后在 Link 选择器指向的下一个页面内抓取数据,我就不一一演示了。

439ad5480dcff5898a66b35a6fbdcd53.png

今天我们还来聊聊 Web Scraper 翻页的技巧。

这次的更新是受一位读者启发的,他当时想用 Web scraper 爬取一个分页器分页的网页,却发现我之前介绍的分页器翻页方法不管用。我研究了一下才发现我漏讲了一种很常见的翻页场景。

在 web scraper 翻页——分页器翻页的文章里,我们讲了如何利用 Element Click 选择器模拟鼠标点击分页器进行翻页,但是把同样的方法放在豆瓣 TOP 250 上,翻页到第二页时抓取窗口就会自动退出,一条数据都抓不到。

其实主要原因是我没有讲清楚这种方法的适用边界。

通过  Element Click 点击分页器翻页,只适用于网页没有刷新的情况,我在分页器那篇文章里举了蔡徐坤微博评论的例子,翻页时网页是没有刷新的:

仔细看下图,链接发生了变化,但是刷新按钮并没有变化,说明网页并没有刷新,只是内容变了

a303b3140e27738841c3298cda853b96.gif

而在 豆瓣 TOP 250 的网页里,每次翻页都会重新加载网页:

仔细看下图,链接发生变化的同时网页刷新了,有很明显的 loading 转圈动画

3a3cdde89fd01f0e73fd45006d5a14f8.gif

其实这个原理从技术规范上很好解释:

- 当一个 URL 链接是 # 字符后数据变化时,网页不会刷新;

- 当链接其他部分变化时,网页会刷新。

当然这个只是随口提一下,感兴趣的同学可以去这个链接研究一下,不感兴趣可以直接跳过。

1.创建 Sitemap

本篇文章就来讲解一下,如何利用 Web Scraper 抓取翻页时会刷新网页的分页器网站。

这次的网页我们选用最开始练手 Web Scraper 的网站——豆瓣电影 TOP250:

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

像这种类型的网站,我们要借助 Link 选择器来辅助我们翻页。Link 标签我们在上一节介绍过了,我们可以利用这个标签跳转网页,抓取另一个网页的数据。这里我们利用 Link 标签跳转到分页网站的下一页

首先我们用 Link 选择器选择下一页按钮,具体的配置可以见下图:

a231cad57026d963259b1a1e379a0e4a.png

这里有一个比较特殊的地方:Parent Selectors ——父选择器。

之前我们都没有碰过这个选择框的内容,next_page 这次要有两个父节点——_root 和 next_page,键盘按 shift 再鼠标点选就可以多选了,先按我说的做,后面我会解释这样做的理由。

保存 next_page 选择器后,在它的同级下再创建 container 节点,用来抓取电影数据:

112bb030e02a8a79fcd69c42e124f6f8.png

这里要注意:翻页选择器节点 next_page 和数据选择器节点 container 是同一级,两个节点的父节点都是两个:_root 和 next_page:

d61cfd7850eaa9c93ec569e2662e9cc6.png

因为重点是 web scraper 翻页技巧,抓取的数据上我只简单的抓取标题和排名:

5bde67733c5072b5c4bd41e2b610b2d9.png

然后我们点击 Selector graph 查看我们编写的爬虫结构:

a26e229a1d4bbe544a2032b9c5a9f488.png

可以很清晰的看到这个爬虫的结构,可以无限的嵌套下去:

ba26aeacfed77c0383193c43081592fb.png

点击 Scrape,爬取一下试试,你会发现所有的数据都爬取下来了:

5207a75d67afd2cfed05425c4afe9d7e.png

2.分析原理

按照上面的流程下来,你可能还会比较困扰,数据是抓下来了,但是为什么这样操作就可以呢,为什么 next_page 和 container 要同级,为什么他们要同时选择两个父节点:_root 和 next_page?

产生困扰的原因是因为我们是倒叙的讲法,从结果倒推步骤;下面我们从正向的思维分步讲解。

首先我们要知道,我们抓取的数据是一个树状结构,_root 表示根节点,就是我们的抓取的第一个网页,我们在这个网页要选择什么东西呢?

4f2ddac273ea2a26f294543791b5548b.png

1.一个是下一页的节点,在这个例子里就是用 Link  选择器选择的 next_page

2.一个是数据节点,在这个例子里就是用 Element  选择器选择的 container

因为 next_page 节点是会跳转的,会跳到第二页。第二页除了数据不一样,结构和第一页还是一样的,为了持续跳转,我们还要选择下一页,为了抓取数据,还得选择数据节点:

802bc9502d6015b613cb662dba2aca1c.png

如果我们把箭头反转一下,就会发现真相就在眼前,next_page 的父节点,不正好就是 _root 和 next_page  吗?container 的父节点,也是  _root 和 next_page!

9cc86cf5863b95d70489befe72f3c702.png

到这里基本就真相大白了,不理解的同学可以再多看几遍。像 next_page 这种我调用我自己的形式,在编程里有个术语——递归,在计算机领域里也算一种比较抽象的概念,感兴趣的同学可以自行搜索了解一下。

3.sitemap 分享

下面是这次实战的 Sitemap,同学们可以导入到自己的 web scraper 中进行研究:

{"_id":"douban_movie_top_250","startUrl":["https://movie.douban.com/top250?start=0&filter="],"selectors":[{"id":"next_page","type":"SelectorLink","parentSelectors":["_root","next_page"],"selector":".next a","multiple":true,"delay":0},{"id":"container","type":"SelectorElement","parentSelectors":["_root","next_page"],"selector":".grid_view li","multiple":true,"delay":0}]}

● 简易数据分析(三):Web Scraper 批量抓取豆瓣数据与导入已有爬虫

● 简易数据分析(五):Web Scraper 翻页、自动控制抓取数量 & 父子选择器

● 简易数据分析(七):Web Scraper 抓取表格、分页器翻页数据

·END·

图雀社区

汇聚精彩的免费实战教程

b363f1b7a089c9f7b396419a328b8fcc.png

关注公众号回复 z 拉学习交流群

喜欢本文,点个“在看”告诉我

c24e5f86b886c056f6c87224876da784.png
Scrapy是一个强大的Python网络爬虫框架,用于高效地抓取网站数据。如果你想要利用Scrapy从当当网抓取图书数据,首先你需要按照以下步骤操作: 1. **安装和配置Scrapy**: - 如果还没有安装,通过`pip install scrapy`命令安装Scrapy。 - 创建一个新的Scrapy项目,运行`scrapy startproject book_scraper`。 2. **创建 spiders**: 在`book_scraper/spiders`目录下创建一个名为`dd_book_spider.py`的文件,这是爬虫的核心部分。开始时,可以使用默认的Spider模板: ```python import scrapy class DangDangBookSpider(scrapy.Spider): name = 'dangdang_book' allowed_domains = ['category.dangdang.com'] start_urls = ['https://category.dangdang.com/cp01.01.02.00.00.00.html'] def parse(self, response): # 这里需要分析HTML结构,找到图书数据所在的元素并解析 pass ``` 3. **解析HTML**: 对于当当网的具体页面结构,你需要查看源代码确定图书信息(如书名、价格、链接等)存储在哪一部分。可能需要使用XPath或CSS选择器来定位元素。例如,你可以查找class或id包含"book-name"、"price"的元素。 4. **提取数据**: 将找到的数据添加到`yield item`语句中,定义一个Item类来保存数据。例如: ```python class BookItem(scrapy.Item): title = scrapy.Field() price = scrapy.Field() link = scrapy.Field() def parse(self, response): books = response.css('div.some-class') # 更改为你找到的元素 for book in books: yield { 'title': book.css('span.book-name::text').get(), 'price': book.css('.price::text').get(), 'link': book.css('a::attr(href)').get(), } ``` 5. **下载和保存数据**: 确保设置好`settings.py`中的`FEED_FORMAT`和`FEED_URI`,然后Scrapy将自动下载数据并将其保存为CSV、JSON或其他指定格式。 6. **运行爬虫**: 最后,在项目的命令行工具中运行`scrapy crawl dangdang_book`,Scrapy就会开始抓取数据了。 注意:实时网站结构可能会有变化,因此在实际操作时可能需要调整选择器。同时,频繁抓取可能导致IP被封禁,所以请遵守网站的robots.txt规则,并尽量减少请求频率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值