我们的骄傲!非遗数据采集,来自官方的数据,Python爬虫无所不爬

“Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。”

本次要抓取的数据为《中国非物质文化遗产数字博物馆》,仅技术学习。 有一说一,非遗数据网站做的非常漂亮。

目标数据源分析

目标站点:http://www.ihchina.cn/,数据存在下图所示位置: 我们的骄傲!非遗数据采集,来自官方的数据,Python爬虫无所不爬 原则上可以针对所有分类抓取,为降低网站访问频率,只采集单一分类,即 http://www.ihchina.cn/project#target1

我们的骄傲!非遗数据采集,来自官方的数据,Python爬虫无所不爬 页面数据为异步加载,通过点击分页获得如下数据:

http://www.ihchina.cn/Article/Index/getProject.html?province=&rx_time=&type=&cate=&keywords=&category_id=16&limit=10&p=1
http://www.ihchina.cn/Article/Index/getProject.html?province=&rx_time=&type=&cate=&keywords=&category_id=16&limit=10&p=2
复制代码

其中参数分别为:

  • province:所属地区;
  • rx_time:公布时间;
  • type:类别;
  • cate:类型;
  • keywords:关键词;
  • category_id:分类 ID;
  • limit:每页数据量;
  • p:页码。

本案例整体代码应该与上一案例相似,重点要看的是本次的数据返回。下图为服务器响应数据,其中核心数据存在于 list 当中,但开发人员将分页格式进行了返回,分页 HTML 标签进行了返回,以上数据在部分项目中存在参考价值。 我们的骄傲!非遗数据采集,来自官方的数据,Python爬虫无所不爬

编码时间

本次为 threading 模块的最后一个案例,在初级爬虫阶段,掌握基本的多线程应用即可。

在实测过程中,有一个经典的采集技巧可以使用,即测试服务器单次接口最大返回数据量,在本案例中,你可以手动修改上述请求地址的 limit 参数,例如将其修改为 100,该值会返回 100 条数据。

出现上述情况,就说服务器对单次返回数据没有限制,所以原则上你是可以直接修改为 3610(目标分类所有数据)的。

这样就可以实现一次访问接口,获取全部数据(不过当返回的数据量大时,接口相应速度会变慢,建议根据实际情况调整) 。

完整代码如下所示

import threading
import requests
import random

class Common:
    def __init__(self):
        pass

    def get_headers(self):
        uas = [
            "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)",
            "你自己的UA值,或者可以从之前的博客中获取"
        ]
        ua = random.choice(uas)
        headers = {
            "user-agent": ua,
            "referer": "https://www.baidu.com"
        }
        return headers


def run(index, url, semaphore, headers):
    semaphore.acquire()  # 加锁
    res = requests.get(url, headers=headers, timeout=5)
    res.encoding = 'utf-8'
    text = res.text
    save(index,text)
    semaphore.release()  # 释放

# 存储的数据中文进行了 UNICODE 编码,分析的时候注意转化
def save(index, text):
    with open(f"./非遗数据/{index}.json", "w", encoding="utf-8") as f:
        f.write(f"{text}")
    print("该URL地址数据写入完毕")


if __name__ == '__main__':
    c = Common()
    url_format = 'http://www.ihchina.cn/Article/Index/getProject.html?province=&rx_time=&type=&cate=&keywords=&category_id=16&limit=10&p={}'
    # 拼接URL,全局共享变量,362 页直接设置,没有动态获取
    urls = [url_format.format(i) for i in range(1, 362)]
    # 最多允许5个线程同时运行
    semaphore = threading.BoundedSemaphore(5)
    for i, url in enumerate(urls):
        t = threading.Thread(target=run, args=(i, url, semaphore, c.get_headers()))
        t.start()
    while threading.active_count() != 1:
        pass
    else:
        print('所有线程运行完毕')
复制代码

收藏时间

代码仓库地址:codechina.csdn.net/hihell/pyth…,去给个关注或者 Star 吧。

数据采集过程中,产生的 JSON 数据

==来都来了,不发个评论,点个赞,收个藏吗?==

今天是持续写作的第 206 / 365 天。 可以关注我,点赞我、评论我、收藏我啦。


猜你喜欢

转载自juejin.im/post/7080329581902692365