会员购项目面试题解析:高效数据抓取与异常处理

会员购项目

亮点

  • 日志记录信息
  • 协程异步抓取数据,大大提高抓取速度
  • 捕获异常,并添加重试机制

源码

import logging
import timeimport requests
import asyncio
import aiohttp
from aiohttp import ContentTypeError
import csv# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s : %(message)s')# 解析数据
def parse_data(data):if data:for meeting in data:project_id = meeting['project_id']project_name = meeting['project_name']start_time = meeting['start_time']venue_name = meeting['venue_name']price_low = meeting['price_low'] / 100price_high = meeting['price_high'] / 100yield {'project_id': project_id,'project_name': project_name,'start_time': start_time,'venue_name': venue_name,'price_low': price_low,'price_high': price_high}# 保存至csv文件中
def save_file(city_info, city_id):if city_info:with open(f'{city_id}.csv', 'a+', newline='', encoding='utf-8') as f:writer = csv.writer(f)writer.writerow([f'{city_info["project_id"]}', f'{city_info["project_name"]}', f'{city_info["start_time"]}',f'{city_info["venue_name"]}', f'{city_info["price_low"]}', f'{city_info["price_high"]}'])class Myspider(object):types_list = ['演出', '展览', '本地生活']cities_id_list = []failed_urls = []CONCURRENTCY = 4RETRY_LIMIT = 3def __init__(self):self.session = Noneself.semaphore = asyncio.Semaphore(Myspider.CONCURRENTCY)# 获取城市编号并设置类属性@staticmethoddef set_cities_id():headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36 Edg/127.0.0.0'}cities_data = requests.get("https://show.bilibili.com/api/ticket/city/list?channel=4", headers=headers).json()['data']developed_cities_id = [city['id'] for city in cities_data['list']]developing_cities_id = [city['id'] for part in cities_data['more'] for city in part['list']]Myspider.cities_id_list = developed_cities_id + developing_cities_idreturn None# 解决单个任务,爬取相关信息async def get_every_page_info(self, url):async with self.semaphore:logging.info(f"scraping {url}")for attempt in range(Myspider.RETRY_LIMIT):try:async with self.session.get(url) as response:data = await response.json()return data["data"]["result"]except ContentTypeError:logging.info(f"error ocurred when scraping {url}", exc_info=True)except aiohttp.ClientError as e:logging.error(f"ClientError on {url}: {e}", exc_info=True)if attempt < Myspider.RETRY_LIMIT - 1:await asyncio.sleep(2 ** attempt)  # Exponential backoffcontinueexcept aiohttp.ServerDisconnectedError:logging.error(f"Server disconnected: {url}", exc_info=True)if attempt < Myspider.RETRY_LIMIT - 1:await asyncio.sleep(2 ** attempt)continueMyspider.failed_urls.append(url)return None  # Return None if all retry attempts fail# 获取 此分类下 此城市下 最大页数def get_max_page(self, url):headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36 Edg/127.0.0.0'}response = requests.get(url, headers=headers)data = response.json()return data["data"]["numPages"]# 主方法, 获取任务列表, 开4个协程去抓async def main(self):headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36 Edg/127.0.0.0'}# 初始化session(主要加header头信息以及代理,cookie等头信息)async with aiohttp.ClientSession(headers=headers) as session:self.session = sessionfor type in Myspider.types_list:for city_id in Myspider.cities_id_list:begin_url = "https://show.bilibili.com/api/ticket/project/listV2?version=134&page=1&pagesize=16&area={}&filter=&platform=web&p_type={}".format(city_id, type)max_page = self.get_max_page(begin_url)# 生成任务列表scrapy_tasks = [self.get_every_page_info("https://show.bilibili.com/api/ticket/project/listV2?version=134&page={}&pagesize=16&area={}&filter=&platform=web&p_type={}".format(page, city_id, type)) for page in range(1, max_page + 1)]# 并发执行任务,获取执行结果scrapy_results = await asyncio.gather(*scrapy_tasks)# 解析结果数据for result in scrapy_results:data = parse_data(result)for city_info in data:print(city_info)save_file(city_info, city_id)# 关闭连接await self.session.close()if __name__ == '__main__':# 开始时间start_time = time.time()# 获取城市编号,设置类属性cities_id_listMyspider.set_cities_id()# 初始化Myspiderspider = Myspider()# 创建事件循环池loop = asyncio.get_event_loop()# 注册loop.run_until_complete(spider.main())# 结束事件end_time = time.time()logging.info(f"total_time: {end_time - start_time}")# print(spider.get_max_page('https://show.bilibili.com/api/ticket/project/listV2?version=134&page=1&pagesize=16&area=110100&filter=&platform=web&p_type=%E5%85%A8%E9%83%A8%E7%B1%BB%E5%9E%8B'))

更多精致内容: [CodeRealm]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BB6kKZj6-1722175080359)(https://i-blog.csdnimg.cn/direct/e18ac94120d945d28ffc46243559ba96.png#pic_center)]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/50336.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

因为媳妇的一句话,我做了一个AI画图软件

因为媳妇的一句话&#xff0c;我做了一个AI画图软件 T恤的配图 前些天媳妇参加了一个创业比赛&#xff0c;其中一个比赛任务是参赛成员需要穿主题队服&#xff0c;队服的图案完全需要自己设计&#xff0c;需要独一无二还得漂亮。 问我&#xff1a;“能不能用AI做一张图&#…

Python酷库之旅-第三方库Pandas(052)

目录 一、用法精讲 191、pandas.Series.drop方法 191-1、语法 191-2、参数 191-3、功能 191-4、返回值 191-5、说明 191-6、用法 191-6-1、数据准备 191-6-2、代码示例 191-6-3、结果输出 192、pandas.Series.droplevel方法 192-1、语法 192-2、参数 192-3、功能…

C# 介绍

文章目录 一. 一个简单的helloworld二. 程序结构三. 类型和变量四. 表达式1. f(x)2. []3. typeof4. default5. new6. checked和unchecked7. sizeof8. 移位9. is和as10. null合并 五. 语句六. 类和对象1. 可访问性2. 类型参数3. 基类和派生类4. 字段5. 方法6. 参数7. 扩展方法&a…

【算法】离散化与区间合并

离散化 有些情况下&#xff0c;数字的值的绝对大小并不重要&#xff0c;而相对大小很重要。“离散化”是用数字的相对值代替它们的绝对值。 把分布广而稀疏的数据转化为密集分布&#xff0c;从而能够让算法更快速&#xff0c;更省空间地处理。 离散化三步骤&#xff1a; 排…

53.综合实验:UART接收图像、写入RAM、通过TFT显示

&#xff08;1&#xff09;设计定义&#xff1a;UART_RX模块接收数据&#xff0c;通过写入逻辑写入RAM存储器中&#xff0c;然后通过读取逻辑&#xff0c;从RAM中读出数据&#xff0c;发送给TFT显示屏。 &#xff08;2&#xff09;FPGA逻辑资源有限&#xff0c;因此设置128 * 1…

go包管理

golang包管理的方式有哪些&#xff1f; Golang包发展历史 官方推荐的有很多包管理方式&#xff1a; 主要有几种&#xff1a; GOPATH、Godep、Glide、Govendor、GOModules 记住这几种 GOPATH < GO1.5 GOVendor >GO1.5 GOModules >GO1.11 GOPATH模式 go语言诞生就有 2…

新生报到系统2024((代码+论文+ppt)

下载在最后 技术栈: ssmmysqljsp 展示: 下载地址: CSDN现在上传有问题,有兴趣的朋友先收藏.正常了贴上下载地址 备注:

docker安装部署elasticsearch7.15.2

docker安装部署elasticsearch7.15.2 1.拉取es镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:7.15.2如果不想下载或者镜像拉去太慢可以直接下载文章上面的镜像压缩包 使用镜像解压命令 docker load -i elasticsearch-7-15-2.tar如下图所示就表示镜像解压成…

Qt+OpenCascade开发笔记(二):windows开发环境搭建(二):Qt引入occ库,搭建基础工程模板Demo和发布Demo

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/140763014 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

51单片机嵌入式开发:19、STC89C52R控制LCD1602码表+数码管+后台数显(串口)

STC89C52R控制LCD1602码表数码管后台数显&#xff08;串口&#xff09; 1 概述1.1 项目概述1.2 项目组成部分1.3 功能描述 2 开发环境2.1 支持设备2.2 硬件电路 3 软件代码工程4 演示4.1 Proteus仿真4.2 实物演示 5 总结 1 概述 1.1 项目概述 本项目旨在利用STC89C52R单片机实…

Elasticsearch 与 MySQL 在查询和插入性能上的深度剖析

在当今的数据处理领域&#xff0c;选择合适的数据库对于应用的性能和效率至关重要。Elasticsearch 和 MySQL 作为两款常用的数据库&#xff0c;它们在查询和插入操作上的性能表现各有千秋。本文将对这两款数据库在这两个关键操作上进行详细的对比分析。 一、引言 随着数据量的…

Postman API版本兼容性测试:确保无缝集成的策略

Postman API版本兼容性测试&#xff1a;确保无缝集成的策略 在API开发过程中&#xff0c;随着时间的推移&#xff0c;API会经历多个版本的迭代。确保新版本与旧版本之间的兼容性对于维护现有用户基础和集成至关重要。Postman提供了多种工具和功能&#xff0c;可以帮助测试人员…

FastDDS中的线程梳理

目录 线程预览 我们承担ROS&#xff0c;FastDDS&#xff0c;C&#xff0c;cmake等技术的项目开发和专业指导和培训&#xff0c;有10年相关工作经验&#xff0c;质量有保证&#xff0c;如有需要请私信联系。 线程预览 NameTypeCardinality线程名DescriptionEventGeneral每个Dom…

后端笔记(1)--javaweb简介

1.JavaWeb简介 ​ *用Java技术来解决相关web互联网领域的技术栈 1.网页&#xff1a;展现数据 2.数据库&#xff1a;存储和管理数据 3.JavaWeb程序&#xff1a;逻辑处理 2.mysql 1.初始化Mysql mysqld --initialized-insecure2.注册Mysql服务 mysqld -install3.启动Mysql…

USB3.0的等长要求到底是多少?

USB2.0与USB3.0接口的PCB布局布线要求PCB资源PCB联盟网 - Powered by Discuz! (pcbbar.com) 90欧姆阻抗&#xff0c;走差分线&#xff1a; 重点来了&#xff1a;

第十九届全国大学生智能汽车竞赛地平线创意组在武汉理工大学隆重开幕

7月27日上午&#xff0c;第十九届全国大学生智能汽车竞赛地平线创意组智慧医疗赛道全国选拔赛开幕式隆重举行&#xff0c;大赛由中国自动化学会、第十九届全国大学生智能汽车竞赛组织委员会主办&#xff0c;武汉理工大学、地平线、古月居承办。首年即吸引来自全国各地280支队伍…

每日一题——第三十五题

题目&#xff1a;有一个文本文件numbers.txt&#xff0c;其中有20个整数&#xff0c;每个整数占一行&#xff0c;编写程序将这些整数从小到大顺序排好后&#xff0c;重新写入到该文件中&#xff0c; 要求排序前和排序后都要输出该文件的内容。 #include<stdio.h> #inclu…

国内乳品领军企业『君乐宝』SRM一期项目成功上线,企企通助力企业采购数字化再升级,二期项目正式启航!

近日&#xff0c;企企通为君乐宝乳业集团&#xff08;以下简称“君乐宝”&#xff09;打造的采购供应链管理系统一期项目成功上线运行&#xff0c;基于双方的信任基础与协作模式将再次携手深化合作&#xff0c;构建全品类、全流程、全场景、全模式的采购数字化管理闭环&#xf…

如何为 5G 小型基站部署选择振荡器

5G 网络频谱频率更高、覆盖范围更短&#xff0c;因此比前几代网络密度更高。超高速 5G 回程 (mmWave) 在很大程度上依赖于小型基站&#xff0c;不仅是为了覆盖范围&#xff0c;也是为了速度。除此之外&#xff0c;O-RAN 联盟等举措为 RAN 生态系统提供了更多选择&#xff0c;但…

Scrapy + Django爬虫可视化项目实战(一)

目录 一、项目介绍 (一) 项目背景 (二) 项目介绍 二、系统实现 (一) 爬虫 1. 实现步骤 一、爬取字段 二、分析页面 三、具体实现 2. 爬虫结果 系列文章 Python升级打怪—Django入门 Python升级打怪—Scrapy零基础小白入门 实现技术 ScrapyDjangoEcharts 一、项目…