【Python爬虫实战入门】:全球天气信息爬取

文章目录

      • 一、爬取需求
      • 二、所需第三方库
        • 2.1 简介
      • 三、实战案例
      • 四、完整代码

一、爬取需求

目标网站http://www.weather.com.cn/textFC/hb.shtml
需求:爬取全国的天气(获取城市以及最低气温)
目标urlhttp://www.weather.com.cn/textFC/hz.shtml

二、所需第三方库

requests
BeautifulSoup4

安装

requestspip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple some-package
BeautifulSoup4pip install BeautifulSoup4 -i https://pypi.tuna.tsinghua.edu.cn/simple some-package

2.1 简介

requests模块

官方文档https://requests.readthedocs.io/projects/cn/zh-cn/latest/
requests 是 Python 编程语言中一个常用的第三方库,它可以帮助我们向 HTTP 服务器发送各种类型的请求,并处理响应。

  • 向 Web 服务器发送 GET、POST 等请求方法;
  • 在请求中添加自定义标头(headers)、URL 参数、请求体等;
  • 自动处理 cookies;
  • 返回响应内容,并对其进行解码;
  • 处理重定向和跳转等操作;
  • 检查响应状态码以及请求所消耗的时间等信息。

BeautifulSoup4模块

官方文档https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/
Beautiful Soup 是一个 可以从 HTML 或 XML 文件中提取数据的 Python 库。它能用你喜欢的解析器和习惯的方式实现 文档树的导航、查找、和修改。

下表描述了几种解析器的优缺点:
在这里插入图片描述
注意:如果一段文档格式不标准,那么在不同解析器生成的 Beautiful Soup 数可能不一样。 查看 解析器之间的区别 了解更多细节。

数据提取之CSS选择器

  • 熟悉前端的同学对 css 选择器一定不会陌生,比如 jquery 中通过各种 css 选择器语法进行 DOM 操作等
  • 学习网站http://www.w3cmap.com/cssref/css-selectors.html

在爬虫中使用css选择器,代码教程

>>> from requests_html import session# 返回一个Response对象
>>> r = session.get('https://python.org/')# 获取所有链接
>>> r.html.links
{'/users/membership/', '/about/gettingstarted/'}# 使用css选择器的方式获取某个元素
>>> about = r.html.find('#about')[0]>>> print(about.text)
About
Applications
Quotes
Getting Started
Help
Python Brochure

三、实战案例

目标网站:http://www.weather.com.cn/textFC/hb.shtml

思路分析:

  1. 通过find方法,定位的div class=conMidtab2
  2. 通过find_all方法,找所有的tr标签

函数功能

  1. 得到网页源码
  2. 解析数据
  3. 保存数据
  4. 主函数

程序框架

import requests
from bs4 import BeautifulSoup
# 获取网页源码
def get_html():pass
# 解析数据
def parse_html():pass
# 保存数据
def save_data():pass
# 主函数
def main():pass

获取网页源码
在主函数中进行传参调用

# 获取网页源码
def get_html(url):html = requests.get(url)html.encoding = 'utf-8'# print(html.text)return html.text# 主函数
def main():url = 'http://www.weather.com.cn/textFC/hz.shtml'html = get_html(url)
main()

解析数据
get_html函数的返回值(网页源码)作为参数传给parse_html函数

# 主函数
def main():url = 'http://www.weather.com.cn/textFC/hz.shtml'html = get_html(url)parse_html(html)
main()

对于parse_html函数,要将传入的网页源码进行解析,获取我们想要的数据。
在这里插入图片描述
通过观察元素,每一个class="conMidtab2"的div标签就代表一个省份,那么他的父级元素class="conMidtab"的div标签就包含三个省份的天气信息,了解了这些,剩下的我们只需要根据元素之间的关系,一步步提取我们想要的数据即可。

# 解析数据
def parse_html(html):# 创建对象soup = BeautifulSoup(html, 'lxml')conMidtab = soup.find('div', class_="conMidtab")tables = conMidtab.find_all('table')# print(tables)for table in tables:trs = table.find_all('tr')[2:]# print(trs)for index, tr in enumerate(trs):tds = tr.find_all('td')# print(tds)city = list(tds[1].stripped_strings)[0]  # 城市temp = tds[-2].string  # 最低气温print(city, temp)break

在这里插入图片描述
但是,这里出现了一个问题,那就是我们要打印城市信息的时候,只能打印出第一个城市,后面的城市无法打印出来,通过查看元素后我们会发现,除了第一个城市是在第二个td标签里面,其余城市都在第一个td标签里面,所以在这里我们要将循环改一下,同时还要加一个判断,只要是第一个城市就去第二个td标签,其余的取第一个td标签
在这里插入图片描述
想要实现这种效果,我们就要用到一个函数enumerate,这个函数可以将下标和下标对应的值给显示出来。

# 解析数据
def parse_html(html):# 创建对象soup = BeautifulSoup(html, 'lxml')conMidtab = soup.find('div', class_="conMidtab")tables = conMidtab.find_all('table')# print(tables)for table in tables:trs = table.find_all('tr')[2:]# print(trs)for index, tr in enumerate(trs):tds = tr.find_all('td')# print(tds)if index == 0:  # 第一个城市取第二个td标签city = list(tds[1].stripped_strings)[0]  # 城市else:  # 其余的取第一个td标签city = list(tds[0].stripped_strings)[0]  # 城市temp = tds[-2].string  # 最低气温print(city, temp)

在这里插入图片描述
更换url查看数据信息
在主函数里面去更换url,然后查看打印的数据信息是否正确。运行后发现前面的都是正确的,直到更换到港澳台1地区时就出现了问题。

# 主函数
def main():# url = 'http://www.weather.com.cn/textFC/hz.shtml'  # 华中地区# url = 'http://www.weather.com.cn/textFC/hb.shtml'  # 华北地区url = 'http://www.weather.com.cn/textFC/gat.shtml'  # 港澳台地区html = get_html(url)parse_html(html)
main()

在这里插入图片描述
在这里插入图片描述
我们发现,我们无法在元素中发现问题,那么我们现在就应该查看一下网页源代码。
在这里插入图片描述
查看网页源代码之后可以发现,他所在的table标签是没有结束标签的,后面的城市的table标签也没有结束标签,这也就导致了数据混乱。
想要解决这个问题,就需要更换一下解析器。上面在提到BeautifulSoup4时的解析器,我们发现html5lib这个解析器拥有最好的容错性。
在这里插入图片描述
下载pip install html5lib

# 解析数据
def parse_html(html):# 创建对象soup = BeautifulSoup(html, 'html5lib')  # 将lxml换成html5libconMidtab = soup.find('div', class_="conMidtab")tables = conMidtab.find_all('table')# print(tables)for table in tables:trs = table.find_all('tr')[2:]# print(trs)for index, tr in enumerate(trs):tds = tr.find_all('td')# print(tds)if index == 0:  # 第一个城市取第二个td标签city = list(tds[1].stripped_strings)[0]  # 城市else:  # 其余的取第一个td标签city = list(tds[0].stripped_strings)[0]  # 城市temp = tds[-2].string  # 最低气温print(city, temp)

在这里插入图片描述
页面切换
要实现页面切换首先我们要观察一下不同页面的url

华北:http://www.weather.com.cn/textFC/hb.shtml
东北:http://www.weather.com.cn/textFC/db.shtml
华南:http://www.weather.com.cn/textFC/hn.shtml
华中:http://www.weather.com.cn/textFC/hz.shtml
港澳台:http://www.weather.com.cn/textFC/gat.shtml

我们发现,这些url的不同之处就在于后面的字母的不同,而这些字母又恰好是地区的首字母,那么我们只需要将这些地区的首字母存入到一个列表当中,循环之后就可以实现页面的切换。

# 主函数
def main():district = ['hb', 'db', 'hd', 'hz', 'hn', 'xb', 'xn', 'gat']# url = 'http://www.weather.com.cn/textFC/hz.shtml'# url = 'http://www.weather.com.cn/textFC/hb.shtml'for dist in district:url = f'http://www.weather.com.cn/textFC/{dist}.shtml'html = get_html(url)parse_html(html)
main()

数据保存
定义一个全局变量的列表list_data,在解析数据的第二层循环中定义一个字典,将城市和最低气温添加到字典中去,最后将字典添加到list_data列表中。

# 保存数据
def save_data():with open('全国天气.csv', 'w', encoding='utf-8-sig', newline='') as f:writer = csv.DictWriter(f, fieldnames=('城市', '最低气温'))writer.writeheader()writer.writerows(list_data)

在这里插入图片描述

四、完整代码

import requests
from bs4 import BeautifulSoup
import csvlist_data = []
# 获取网页源码
def get_html(url):html = requests.get(url)html.encoding = 'utf-8'# print(html.text)return html.text# 解析数据
def parse_html(html):# 创建对象soup = BeautifulSoup(html, 'html5lib')  # 将lxml换成html5libconMidtab = soup.find('div', class_="conMidtab")tables = conMidtab.find_all('table')# print(tables)for table in tables:trs = table.find_all('tr')[2:]# print(trs)for index, tr in enumerate(trs):dic = {}tds = tr.find_all('td')# print(tds)if index == 0:  # 第一个城市取第二个td标签city = list(tds[1].stripped_strings)[0]  # 城市else:  # 其余的取第一个td标签city = list(tds[0].stripped_strings)[0]  # 城市dic['城市'] = citytemp = tds[-2].string  # 最低气温dic['最低气温'] = templist_data.append(dic)# 保存数据
def save_data():with open('全国天气.csv', 'w', encoding='utf-8-sig', newline='') as f:writer = csv.DictWriter(f, fieldnames=('城市', '最低气温'))writer.writeheader()writer.writerows(list_data)# 主函数
def main():district = ['hb', 'db', 'hd', 'hz', 'hn', 'xb', 'xn', 'gat']# url = 'http://www.weather.com.cn/textFC/hz.shtml'# url = 'http://www.weather.com.cn/textFC/hb.shtml'for dist in district:url = f'http://www.weather.com.cn/textFC/{dist}.shtml'html = get_html(url)parse_html(html)save_data()  # 数据保存main()

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

C++ | Leetcode C++题解之第71题简化路径

题目&#xff1a; 题解&#xff1a; class Solution { public:string simplifyPath(string path) {auto split [](const string& s, char delim) -> vector<string> {vector<string> ans;string cur;for (char ch: s) {if (ch delim) {ans.push_back(mov…

粤嵌—2024/4/26—跳跃游戏 ||

代码实现&#xff1a; 方法一&#xff1a;回溯 历史答案剪枝优化——超时 int *dis;void dfs(int k, int startindex, int *nums, int numsSize) {if (dis[startindex] < k) {return;}dis[startindex] k;for (int i 0; i < nums[startindex]; i) {if (startindex i &…

好久不见,回来看看七年前的你

今天在网上搜东西&#xff0c;突然想到之前在网上记录的点滴成长&#xff0c;回来看看~ 来看看那些年走过的路&#xff0c;小伙还挺真实&#xff0c;有些想法~ 那时&#xff0c;一起在网上记录文字的人&#xff0c;也都慢慢失去了联系~ 确实&#xff0c;深有感触&#xff0c;…

安卓玩机工具----一键备份手机分区 防止全檫除或者格机导致安全数据分区丢失

工具说明; 目前玩机root后有很多格机脚本。模块等等误刷会导致基带信号等等问题&#xff0c;在前面的博文中我有介绍过备份主要数据分区的重要性 。其实对于不了解root和不安装有些模块 外挂等等需要的友友不建议对手机进行root。root后对于手机安全性会有所降低。对于玩家来说…

八.吊打面试官系列-Tomcat优化-深入源码剖析Tomcat如何打破双亲委派

前言 上篇文章《Tomcat优化-深入Tomcat底层原理》我们从宏观上分析了一下Tomcat的顶层架构以及核心组件的执行流程。本篇文章我们从源码角度来分析Tomcat的类加载机制&#xff0c;且看它是如何打破JVM的ClassLoader双亲委派的 Tomcat ClassLoader 初始化 Tomcat的启动类是在…

分布式锁-快速入门

文章目录 前言一、基础概念1.1 什么是锁1.2 什么是分布式锁1.3 锁和事务的区别二、分布式锁基础理论2.1 为什么要使用分布式锁2.2 分布式锁特性2.3 分布式锁的实现方式总结前言 由于在平时的工作中,线上服务器是分布式多台部署的,经常会面临解决分布式场景下数据一致性的问题…

python abs函数怎么用

abs()函数是Python的数字函数&#xff0c;用以返回数字的绝对值。 语法 以下是 abs() 方法的语法&#xff1a; abs( x ) 参数 x -- 数值表达式&#xff0c;可以是整数&#xff0c;浮点数&#xff0c;复数。 返回值 函数返回 x&#xff08;数字&#xff09;的绝对值&#x…

新能源汽车动力电池热管理-液冷方案应用原理与应用前景简介

前言 动力电池是新能源汽车的核心部件之一&#xff0c;其性能和寿命直接影响着车辆的续航里程和使用成本。液冷方案作为一种常见的动力电池温控解决方案&#xff0c;被广泛应用于新能源汽车领域。本文将详细介绍液冷方案的原理、发展方向以及市场前景。 一、液冷方案的原理 …

喜报 | 擎创科技荣获NIISA联盟2023年度创新技术特等奖!

为深入实施创新驱动发展战略&#xff0c;紧紧把握全球科技革命和产业变革方向&#xff0c;密切跟踪前沿科技新趋势&#xff0c;经科技部中国民营促进会业务主管部门批准以及国家互联网数据中心产业技术创新战略联盟&#xff08;以下简称联盟&#xff09;总体工作安排&#xff0…

双热点的王炸组合!损失函数+Attention,精度与速度上实现SOTA!

损失函数注意力机制在深度学习领域是一个热门研究方向&#xff0c;它可以提高模型的性能和泛化能力&#xff0c;帮助我们构建更加精确且高效的模型。 具体来说&#xff1a; 通过结合注意力机制的聚焦能力和损失函数的优化指导&#xff0c;模型能够更精确地捕捉数据中的关键信息…

PHP基于vscode医院安全不良事件管理系统源码(AEMS)前端vue2+element+后端laravel8不良事件上报与闭环管理

PHP基于vscode医院安全不良事件管理系统源码&#xff08;AEMS&#xff09;前端vue2element后端laravel8不良事件上报与闭环管理 医院不良事件上报与管理系统结合现代医院管理思路&#xff0c;遵照PDCA全面质量循环管理方法而设计&#xff0c;并在多家大型三甲医院成熟运用。系统…

无偏扭曲区域采样在可微分渲染中的应用

图1. 可微渲染计算光传输方程的导数。为了处理可见性的存在&#xff0c;最近的基于物理的可微渲染器需要显式地找到边界点[Li等人2018; Zhang等人2020]&#xff0c;或者通过启发式方法近似边界贡献[Loubet等人2019]。我们从第一原理出发&#xff0c;开发了一个无偏估计器&#…

销量?模糊销量?精准销量?如何获取淘宝商品销量数据接口

淘宝爬虫商品销量数据采集通常涉及以下几个步骤&#xff1a; 1、确定采集目标&#xff1a;需要明确要采集的商品类别、筛选条件&#xff08;如天猫、价格区间&#xff09;、销量和金额等数据。例如&#xff0c;如果您想了解“小鱼零食”的销量和金额&#xff0c;您需要设定好价…

PyQt6--Python桌面开发(1.安装配置环境)

一.PyQt6简介 PyQt&#xff1a;PyQt是一个功能强大且成熟的GUI框架&#xff0c;基于Qt库。它提供了丰富的组件、布局和主题选项&#xff0c;以及强大的功能和灵活性。PyQt的优点是它具有现代化的外观和丰富的功能&#xff0c;适用于复杂的GUI应用程序。然而&#xff0c;由于Py…

今年去做视频号小店,应该怎么去做!新手快速入门的技巧!

大家好&#xff0c;我是电商小V 在我看来24年一定是视频号小店的分水岭&#xff0c;也就是说从今年开始往后视频号小店的门槛是越来越高了&#xff0c;现在就是越早入场的玩家来说越有利&#xff0c;这点是毋庸置疑的&#xff0c; 想要在视频号小店平台上面有长久的发展&#…

游戏技术人福音!当游戏语音碰到网易云信 ,我服了!

“开黑吗&#xff1f;五黑的那种” 少年时代&#xff0c;放假后偷偷溜进网吧&#xff0c;一边打着游戏&#xff0c;一边连麦吐槽对手的惬意岁月&#xff0c;不仅承载了无数 80 后、90 后&#xff0c;甚至 00 后的青春记忆&#xff0c;也让游戏语音成为了“游戏少年”闲暇生活的…

以中国为目标的DinodasRAT Linux后门攻击场景复现

概述 在上一篇《以中国为目标的DinodasRAT Linux后门剖析及通信解密尝试》文章中&#xff0c;笔者对DinodasRAT Linux后门的功能及通信数据包进行了简单剖析&#xff0c;实现了对DinodasRAT Linux后门心跳数据包的解密尝试。 虽然目前可对DinodasRAT Linux后门的通信数据包进…

github提交不了的问题

开了VPN提交的时候提示这个报错 是需要这两个端口号一致&#xff0c;就能提交了

大数据技术原理与技术简答

1、HDFS中名称节点的启动过程 名称节点在启动时&#xff0c;会将FsImage 的内容加载到内存当中&#xff0c;此时fsimage是上上次关机时的状态。然后执行 EditLog 文件中的各项操作&#xff0c;使内存中的元数据保持最新。接着创建一个新的FsImage 文件和一个空的 Editlog 文件…

WMS仓储管理系统库存分类的详细讲解

在当今日益复杂和快速变化的商业环境中&#xff0c;仓库管理成为了一个企业不可或缺的关键环节。WMS仓储管理系统解决方案凭借其自动化和信息化的优势&#xff0c;为企业带来了革命性的改变&#xff0c;特别是在库存分类方面。接下来&#xff0c;我们将深入探讨WMS仓储管理系统…