思路分享:如何抓取 不同厂商、不同结构的 VPS Plan

2017-04-01 18:02:24 +08:00
 panyanyany

最近做了个抓取 VPS Plan 的爬虫


后来改变思路,决定采用人工识别,但是通过配置表的方式来提取数据,这就是下面的内容。

小广告:
GitHub 地址 vps_spider
项目展示官网 Find All VPS


如何抓取结构复杂的 VPS Plan

Plan 分类

由于不同厂商使用不同的网站,所以他们的 Plan 表也是不一样的,为了能设计出一套通用的解析器,我们先研究下它们的特点:

第一种


Linode: 像这样的情况属于多数,一个节点包含了一个完整的 Plan

第二种


DomainVPS: 这种就比较反直觉了,一个好好的 Plan 被分割到不同的节点里,简直是 VPS 中的杀马特

Plan 解析器逻辑(配置表)

为了避免给每一个网站写一个 spider ,有必要设计一套配置表,通过配置表来告诉解析器不同的网站应该怎么解析

{
    'https://www.linode.com/pricing': PlanSet([
        (('#pricing-larger-plans > div > div > div > div > table > tbody > tr', 'td'), {
            0: values.Name,
            1: values.RAM,
            2: values.CPU,
            3: values.Disk,
            4: values.Traffic,
            5: values.NetworkIn,
            6: values.NetworkOut,
            7: values.Price,
        }),
    ]),
}

如代码如示,这个是 Linode 的配置表,这个配置表结构简单,却具有相当的可扩展性和通用性。

以上代码运行后会得到一个数组:[Plan, Plan, Plan, ...]
其中每个 Plan 里都包含了 Specs 解析单元 的实例

对 Plan 表格中 DOM 结构的预处理

上面的代码只是说明了处理正确表结构的情况,然而现实中有大量表结构是不正常的,那么这种不正常的表,应该如何写配置呢?

如下所示,为 DomainVPS 的配置表:

{
    'http://www.domain.com/hosting/vps/': PlanSet([
        (('#main > div.compgrid > table > tr', 'td', True), {
            1: values.Disk,
            2: values.Traffic,
            11: values.Price,
        }),
        (('#main > div.compgrid > table > tr', 'th', True)), {
            0: values.Name,
        }),
    ]),
}

对特殊 Specs 的特别处理

除了 Plan 表格 会出现特殊结构外,有些奇葩厂商还会弄些标新立异的 Specs 格式。比如:

像这样的情况,我会这样处理:

{
    'http://xxx.ooo': PlanSet([
        (('#main > div.compgrid > table > tr', 'td', True), {
            1: ValueMatch(values.Disk, re.compile("((?P<disk_cnt>\d+)x ?)?(?P<size>\d+)(?P<size_unit>\w+) (?P<disk_type>SSD)")),
            3: ValuePipe(values.Traffic, 
                         [ lambda t: t.replace(',', '').replace('.', '') + ' GB'],
                         values.Traffic
                ),
        }),
    ]),
}

更多配置案例请移步至: urlsolutions.py

2045 次点击
所在节点    分享创造
5 条回复
sunorg
2017-04-01 18:23:37 +08:00
然后有什么用?

做 resell?
panyanyany
2017-04-01 18:25:19 +08:00
r#1 @sunorg 没啥用,练手
panyanyany
2017-04-01 18:26:44 +08:00
r#1 @sunorg 你不觉得用这种配置表的形式,避免了一个个去写 spider 吗?
isCyan
2017-04-01 18:36:41 +08:00
@sunorg 做 affman 啊
ryd994
2017-04-02 06:53:11 +08:00
不错的
参数和逻辑充分解耦了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/352036

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX