我刚才支付了29元,怎么还不能用啊会员功能
652
2022-05-30
本次要抓取的数据为《中国非物质文化遗产数字博物馆》,仅技术学习。
有一说一,非遗数据网站做的非常漂亮。
目标数据源分析
目标站点:http://www.ihchina.cn/,数据存在下图所示位置:
原则上可以针对所有分类抓取,为降低网站访问频率,只采集单一分类,即 http://www.ihchina.cn/project#target1。
页面数据为异步加载,通过点击分页获得如下数据:
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 标签进行了返回,以上数据在部分项目中存在参考价值。
编码时间
本次为 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('所有线程运行完毕')
Python 任务调度
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。