【python爬虫实战】进阶天气虫虫(过程复盘 心得分享)

程序设计过程里的一些心得:

0. 规模较大的程序,往往都是以更小的功能块搭建起来的。如此,为了提升总体程序的构建效率, 笔者发现分“两步走”会比较高效:

        A. 遇到需要反复调试的功能块,可先在另一程序中逐一单独测试某一功能块(这有助于突出模块本身的细节问题)

        B. 最后像搭积木一样将模块放回主题程序中,进行一些接口性的“磨合”

1. 见招拆招,必备的是灵活的思路

相比于上一篇初代爬虫,进阶爬虫的核心特点在于可以提供未来五天天气情况的预测,而这也是程序实现的关键难点。具体而言有如下两方面:

        A. 如何精准获取:

由于要获取的信息较多较细,观察网页html原码,或者参考编译过程中直接用find_all函数获取的结果不难发现,由于网页原码中标签的重复性较大,通过一次find_all获得的可迭代对象可谓是“鱼龙混杂”。

解决方案多层搜索,缩小目标范围:#以获取list_weather为例

weathers = soup.find_all("td",attrs={"width":"20%", "align":"left"})
list_weather = []
for weather in weathers:#预处理weather = weather.find("p")#找到除上述标签外还有标签"p"的weather = weather.find("span")#找到除上述标签外还有标签"span"的if weather:#排除weather为None的情况list_weather.append(weather.string)

AT:find_all返回的对象只可用,且可不断用“find”函数

        B.如何“完美”输出:

笔者在输出这一步碰上一个麻烦:要实现如下的规整输出,就不得不在一次for循环中将日期、气温、天气的值都输出一遍。

但是!麻烦来了,他们三者在find_all后得到的元素个数并不一样,但for循环的更新一次的依据恰恰是根据迭代一次来进行的(迭代一次,for循环进行一次),因此想要实现“优雅“输出大概没有那么容易。

解决方案:预处理

还是以上面的获取list_weather为例,实际上,之所以要专门建立一个list_weather,恰恰是为了将有效元素留在里面,最终list_weather中只留下干净的五个元素。

完整代码如下:

#请求头headers的值需根据电脑信息自行提供哈,具体方法可参考b站视频讲解哈,此处不再赘述

from bs4 import BeautifulSoup
import requests
from pypinyin import pinyin, Style
import time
import os
if __name__ == '__main__':headers = { }mode = 1while mode != -1:try:os.system("cls")mode = 1print("----------勇敢虫虫,不怕困难!----------")print("~让虫虫爬一会~")response = requests.get("http://qq.ip138.com/weather/", headers=headers)response.raise_for_status()soup = BeautifulSoup(response.content, "html.parser", from_encoding="utf-8")provinces = soup.find_all("dd")  # 打印所所有城市名dict_province = {}for idx, province in enumerate(provinces):province_text = province.get_text(strip = True)print(idx, province_text)dict_province.setdefault(idx, province_text)#接收用户选择省份idx_province = int(input("请选择您关注的省对应序号(虫虫只爬得动省份哈, 至于市、区,请期待一下吧~):"))province_chosen = dict_province[idx_province]# pinyin_province = ' '.join([''.join(pinyin(char, style=Style.NORMAL)) for char in province_chosen])pinyin_list_province = []  for char in province_chosen:  # pinyin函数返回的是一个列表,其中包含了每个音节的列表(对于多音字)  # 使用列表推导式将每个音节的列表转换为用空格分隔的字符串  pinyin_chars = ' '.join([''.join(py) for py in pinyin(char, style=Style.NORMAL)])  pinyin_list_province.append(pinyin_chars)  # 最后,使用join函数将所有汉字的拼音连接起来,用空格分隔  pinyin_province = ''.join(pinyin_list_province) #省份    #访问对应省份网址response = requests.get(f"https://qq.ip138.com/weather/{pinyin_province}/", headers=headers)soup = BeautifulSoup(response.content, "html.parser")cities = soup.find_all("a", attrs={"class", "title"})temps = soup.find_all("span", attrs={"class":"temp"})weathers = soup.find_all("span", attrs={"class":"weather"})dict_cities = {}dict_temps = {}dict_weathers = {}idx = 1for city, temp, weather in zip(cities, temps, weathers):city_text = city.get_text(strip = True)print(idx, city.string)dict_cities.setdefault(idx, city_text)dict_temps.setdefault(idx, temp)dict_weathers.setdefault(idx, weather)idx += 1#接收用户输入城市while mode == 1:idx_city = int(input("请选择你要关注的城市对应序号:"))city_chosen = list(dict_cities[idx_city])city_chosen = ''.join(city_chosen[:len(city_chosen)-4])pinyin_list_city = []for char in city_chosen:  # pinyin函数返回的是一个列表,其中包含了每个音节的列表(对于多音字)  # 使用列表推导式将每个音节的列表转换为用空格分隔的字符串  pinyin_chars = ' '.join([''.join(py) for py in pinyin(char, style=Style.NORMAL)])  pinyin_list_city.append(pinyin_chars)  # 最后,使用join函数将所有汉字的拼音从列表中提取出来并连接起来,用空格分隔  pinyin_list_city = pinyin_list_city[:len(pinyin_list_city)]#去掉末尾“天气预报”对应拼音pinyin_city = ''.join(pinyin_list_city) city_temp = dict_temps[idx_city]city_weather = dict_weathers[idx_city]print("\n找到啦:\n{0}市今日{1},温度{2}".format(city_chosen, city_weather.string, city_temp.string))time.sleep(2)mode = int(input("天气虫虫:看完了这座城,接下来要俺做什么嘞?(请输入:-1:结束一切程序/ 0:看看别的省(市、区)/1:看看本省的其他城市)/2:了解下当前城市未来五天天气发展情况 :"))if mode == 2:response = requests.get(f"https://qq.ip138.com/weather/{pinyin_province}/{pinyin_city}.htm", headers=headers)soup = BeautifulSoup(response.content, "html.parser")dates = soup.find_all("p", attrs={"class":"date"})weathers = soup.find_all("td",attrs={"width":"20%", "align":"left"})# weather = weathers.ftemperatures = soup.find_all("td", attrs={"width":"15%", "align":"center"})list_weather = []for weather in weathers:#预处理weather = weather.find("p")weather = weather.find("span")if weather:list_weather.append(weather.string)print(f"--------好滴~未来五天,{city_chosen}天气情况见下哦--------")print("日期".ljust(len("2024-07-01")), "气温".ljust(len("20℃ ~ 28℃ ")), "天气")for date, temp, wehather in zip(dates, temperatures, list_weather):print(date.string, end=" | ")temp = temp.find("p")print(temp.string, end=" | ")print(weather.string)time.sleep(5)mode = int(input("看完了这座城,接下来要我做什么嘞?(请输入:-1:结束一切程序/ 0:看看别的省(市、区)/1:看看本省的其他城市 :"))except requests.RequestException as ex:print(f"网络错误:{ex}")

在vscode上运行可实现如下输出:

~ 本文是笔者超级用心写的,衷心希望能给你带来些许启发! ~

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

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

相关文章

植物大战僵尸融合嫁接版 MAC 版本下载安装详细教程

继植物大战僵尸杂交版火了之后,PVZ改版可谓是百花齐放,最近又有一个非常好玩的模式被开发出来了,他们称为《植物大战僵尸融合嫁接版》 该版本并没有对植物卡牌做改动,而是可以将任意两种植物叠放到一起进行融合,产生新…

玲珑大爆料!deepin Meetup(上海站)议程抢先看!

Linux软件生态正迎来一场革命,随着软件数量的激增,传统的包管理系统逐渐暴露出依赖性强、兼容性差、安全性不足等问题。“玲珑”是一种新型的独立包管理工具集,通过先进的隔离技术和分层管理,为应用提供了一个安全、稳定、高效的运…

202488读书笔记|《365日创意文案》——无聊的 到底是这世间, 还是自己?懂得忘却的人才能前进

202488读书笔记|《365日创意文案》——无聊的 到底是这世间, 还是自己?懂得忘却的人才能前进 1月2月3月4月5月6月7月8月9月10月11月12月 《365日创意文案》WRITES PUBLISHING,一些日常,是烟火,也是幸福的印记。 当下也…

IT之家最新科技热点 | 小米 AI 研究院开创多模态通用模型

人不走空 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌赋:斯是陋室,惟吾德馨 目录 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌…

Python编程学习笔记(1)--- 变量和简单数据类型

1、变量 在学习编程语言之前,所接触的第一个程序,绝大多数都是: print("Hello world!") 接下来尝试使用一个变量。在代码中的开头添加一行代码,并对第二行代码进行修改,如下: message "…

3 个令人惊艳的 AI 开源工具,诞生了!

大家好,今天继续聊聊 AI 科技圈发生的那些事。分享几个最新好玩、实用的AI工具。更多最新技术,文末加入我们。 LivePortrait LivePortrait:一款可以轻松让一幅肖像栩栩如生的工具 它可以精准操控眼睛和嘴唇动作: 让静态照片变为…

python特征相关性可视化分析 - sns.pairplot

seaborn 是一个基于 matplotlib 的 Python 数据可视化库,提供了更高层次的接口来绘制有吸引力的统计图形。pairplot 是 seaborn 中的一个函数,用于绘制数据集中多个变量之间的成对关系图。 基本用法 pairplot 函数可以快速地对数据集中的所有数值变量进…

【AutoencoderKL】基于stable-diffusion-v1.4的vae对图像重构

模型地址:https://huggingface.co/CompVis/stable-diffusion-v1-4/tree/main/vae 主要参考:Using-Stable-Diffusion-VAE-to-encode-satellite-images sd1.4 vae 下载到本地 from diffusers import AutoencoderKL from PIL import Image import torch import to…

第二证券股市资讯:深夜!突然暴涨75%!

一则重磅收买引发医药圈轰动。 北京时间7月8日晚间,美股开盘后,美国生物制药公司Morphic股价一度暴升超75%。音讯面上,生物医药巨子礼来公司官宣,将以57美元/股的价格现金收买Morphic,较上星期五的收盘价溢价79%&…

Yolov10训练,转化onnx,推理

yolov10对于大目标的效果好,小目标不好 一、如果你训练过yolov5,yolov8,的话那么你可以直接用之前的环境就行 目录 一、如果你训练过yolov5,yolov8,的话那么你可以直接用之前的环境就行 二、配置好后就可以配置文件…

身边的故事(十五):阿文的故事:再消失

物镜人非,沧海桑田。像我们这些普通的凡人,哪有什么试错的机会,每走一步都是如履薄冰,小心谨慎,错一步可能就会万劫不复。唉,如果...唉...哪有什么如果... 阿文的房子很快装修完成,入新房那天就…

提高Python爬虫的匿名性:代理ip的配置策略

在当今,网络数据采集作为获取行业信息的重要手段,尤其在竞争激烈的商业环境中,Python作为一种强大的编程语言,广泛应用于开发各种数据爬虫来自动化地抓取网络信息。然而,网站普遍采用防护措施,即使我们合规…

用QFramework重构飞机大战(Siki Andy的)(下01)(06-0? 游戏界面及之后的所有面板)

GitHub // 官网的 全民飞机大战(第一季)-----框架设计篇(Unity 2017.3) 全民飞机大战(第二季)-----游戏逻辑篇(Unity 2017.3) 全民飞机大战(第三季)-----完善…

【Java14】构造器

Java中的构造器在创建对象(实例)的时候执行初始化。Java类必须包含一个或一个以上的构造器。 Java中的构造器类似C中的构造函数。 Java中对象(object)的默认初始化规则是: 数值型变量初始化为0;布尔型变量…

js使用proxy代理监听控制事件

本文为proxy代理的实例应用,有关代理的内容可以参考: js语法---理解反射Reflect对象和代理Proxy对象 监听事件 要监听dom元素的事件,我们会采用回调触发的方式来执行操作, 而触发事件的过程很明显是一个异步操作,异…

【TB作品】51单片机 Proteus仿真 00013红外proteus仿真循迹避障小车

实验报告:智能小车系统设计与实现 一、背景介绍 本实验旨在设计并实现一个基于STC89C52单片机控制的智能小车系统。该系统通过超声波传感器进行避障,通过红外接收器实现远程控制,同时具备循迹功能。整个系统的核心是单片机,它通…

智慧生活新篇章,Vatee万腾平台领航前行

在21世纪的科技浪潮中,智慧生活已不再是一个遥远的梦想,而是正逐步成为我们日常生活的现实。从智能家居的温馨便捷,到智慧城市的高效运转,科技的每一次进步都在为我们的生活增添新的色彩。而在这场智慧生活的变革中,Va…

LabVIEW的JKI State Machine

JKI State Machine是一种广泛使用的LabVIEW架构,由JKI公司开发。这种状态机架构在LabVIEW中提供了灵活、可扩展和高效的编程模式,适用于各种复杂的应用场景。JKI State Machine通过状态的定义和切换,实现了程序逻辑的清晰组织和管理&#xff…

AI实践与学习7_AI解场景Agent应用预研demo

前言 学习大模型Agent相关知识,使用llama_index实现python版的Agent demo,根据AI解题场景知识密集型任务特点,需要实现一个偏RAG的Agent WorkFlow,辅助AI解题。 使用Java结合Langchain4j支持的RAG流程一些优化点以及自定义图结构…

go语言day11 错误 defer(),panic(),recover()

错误: 创建错误 1)fmt包下提供的方法 fmt.Errorf(" 格式化字符串信息 " , 空接口类型对象 ) 2)errors包下提供的方法 errors.New(" 字符串信息 ") 创建自定义错误 需要实现error接口,而error接口…