#8 Web Crawler 1

今天终於要开始写点有用的东西了:网路爬虫。
这次我们就来爬铁人赛的文章吧。

设定希望的资料结构

在做爬虫的第一个步骤是要先设定我们想要得到的资料的结构,这很大程度影响之後拿到一堆资料後的分析程序。
不过,这次我们的目标就是做出每天文章下面那块「每日铁人赛热门 Top 10」,所以结构不会太复杂,只需要平面的存同时间切面的所有文章就行。

// 数据结构
Data = {
    "09/21": [article1, article2, ...], // n 天抓的资料
    "09/22": [article1, article2, ...] // n+1 天抓的资料
}

了解目标网站的结构

在做爬虫的第二个步骤则是要了解目标网站的结构,因为这会涉及到爬虫要怎麽写。

我们可以从铁人赛文章页面看到他有分「主题竞赛」、「技术推广专区」及「自我挑战组」三大区块,但其实「技术推广专区」的文章都包含在「主题竞赛」内了,所以在爬的时候不需要处理「技术推广专区」。

我们估且把那些区块称为 Block

在每个 Block 内呢,我们都可以看到有一个文章的列表,当然,他们被分成很多页,少则 200 ~ 300,多则 500 ~ 600,我们称它为 Page,而每个 Page 内又有许多 Article

因为分页的缘故,网站上的数据结构与我们所希望的数据结构有些不同:

// 网站上的数据结构
Data = {
    "Block1": {
        "Pages": [
            {
                "Articles": [article1, article2, ...]
            }
        ]
    },
    "Block2": {
        "Pages": [
            {
                "Articles": [article1, article2, ...]
            }
        ]
    }
}

我们会希望把它变成:

// 目标数据结构
Data = [article1, article2, ...];

随着时间的增长,我们可以知道 Page 数会增加,但 Block 数是固定的,所以在这里我们 hard code Block 不会有什麽大问题,但对 PageArticle 就不能这样了。为什麽 Article 也不行?因为我们不确定最後一个 Page 会剩多少文章。

执行时可能遇到的问题

再来,我们得先想想爬虫可能会遇到的问题,以及应对方案。

重复或遗漏文章

这个问题会发生的原因是因为爬虫在爬取时是需要时间的,并不是在一个瞬间扫过所有页面,而是一步一步的爬,所以如果当我们在爬的时候有人发表一则新文章,那整个列表就会被推移而重复爬取一则文章或遗失一则文章,取决於爬取方向。

这个问题的处理方法算是蛮简单的,当遗漏文章时,我们自己是不会知道的,顶多发现总文章数与我们爬到的不符,但无法以已爬取资料得到少了哪个文章的资讯,所以我们选择接受「重复」而非「遗漏」,因为重复文章较容易找出,只需要用 Map 之类唯一键值的资料结构就好。

如果你想用「瞬间扫过所有页面」的方式根本性的解决这个问题,请先想想:

  • 你的网路频宽够吗?
  • 服务器的网路频宽够吗?
  • 道德吗?会不会被当成 DDOS?

文章爬取失败

这个问题可就复杂了,可能是我们自己的网路问题、伺服端的网络问题、解析发生错误或不明原因。

处理方法就...设定重试规则吧。

其他问题

一定会有在初始阶段没想到的问题在之後浮现,这时候只能把写好的程序改掉修正问题或忽略它,所以最好还是能先想到,避免白花力气。

明天写 Code 喔

所以你要一定要记得装 Node.js。


每日铁人赛热门 Top 10 (0921)

以 9/21 12:00 ~ 9/22 12:00 文章观看数增加值排名

  1. +330 Day 2:什麽是 SRE
    • 作者: bogay
    • 系列:这个 site 就是逊啦 - SRE 30 天登大人之旅
  2. +209 [Day 03] tinyML开发板介绍
    • 作者: 史蒂芬周
    • 系列:争什麽,把AI和MCU掺在一起做tinyML就对了!
  3. +192 深入浅出 Computed
    • 作者: Chris
    • 系列:Vue.js 进阶心法
  4. +183 06 APCS 考试内容 Overview
    • 作者: skyhong2002
    • 系列:深入高中程序设计能力指标 APCS
  5. +161 #1 JavaScript Easy Go!
    • 作者: JacobLinCool
    • 系列:JavaScript Easy Go!
  6. +157 #4 Array & Object in JavaScript
    • 作者: JacobLinCool
    • 系列:JavaScript Easy Go!
  7. +157 #6 JavaScript & Node.js
    • 作者: JacobLinCool
    • 系列:JavaScript Easy Go!
  8. +151 07 Re: 从零开始的竞程生活
    • 作者: skyhong2002
    • 系列:深入高中程序设计能力指标 APCS
  9. +139 Angular 深入浅出三十天:表单与测试 Day06 - 单元测试实作 - 登入系统 by Template Driven Forms
    • 作者: Leo
    • 系列:Angular 深入浅出三十天:表单与测试
  10. +130 05 - Uptime - 掌握系统的生命徵象 (3/3) - 透过 Kibana 观看心电图及设定警报
    • 作者: 乔叔
    • 系列:乔叔带你上手 Elastic Stack - 探索与实践 Observability

恭喜 bogay 学长封顶


<<:  30天学会C语言: Day 6-当情况从复杂,变成更加复杂...

>>:  30天打造品牌特色电商网站 Day.8 CSS基础

第30篇

在这30天里我自己也学到了很多,从一开始的基础元件使用,到後面的资料库、触控感测等较有难度的程序,但...

django新手村3 -----models 一对多

资料库中的一对多如何在 django实现呢 先在app models.py 创建ClassRoom ...

从 JavaScript 角度学 Python(10) - 容器型别(下)

前言 前一篇我们聊了一些字典有趣的取值方式,所以接下来我想接着继续聊关於字典的部分。 字典取值 在 ...

[Day 26] Web 小厨娘

今天晚餐是我掌厨 妈妈跟我一起备料当二厨 煮了4菜一汤切水果 虽然我觉得煎鱼比较难 但煮饭还是一件很...

Visual Studio程序码签章问题

最近实作ClickOnce出现的一些问题: 将密钥导入 Visual Studio 2019 时出错...