bs4库爬取天气预报

news2025/1/24 5:35:53

Python不仅用于网站开发,数据分析,图像处理,也常用于爬虫技术方向,最近学习了解下,爬虫技术入门一般先使用bs4库,爬取天气预报简单尝试下。

第一步:首先选定目标网站地址

网上查询,天气预报准确率高的官网是“天气网”,网址:http://www.weather.com.cn/

第二步:确定爬取目标数据

本次只是简单学习尝试下。

1,爬取-今天-天气预报(天气情况,最高温度,最低温度);

2,爬取-近7天-天气预报(日期,天气,温度,风力);

  

第三步:确定爬取目标数据网页元素定位

例如:今天-最高温度,页面元素定位,使用浏览器开发调试功能,按  F12 进入。

调试界面左上角箭头点击进入选择元素模式,然后从页面中选择需要查看的元素,然后可以在开发者工具元素(Elements)一栏中定位到该元素源代码的具体位置 。

查看元素属性:可从被定位的源码中查看部分,如class、src,也可在右边的侧栏中查看全部的属性,如下图位置查看

 根据页面元素层级关系,确定bs4库的BeautifulSoup选择元素位置,根据元素标签,属性,层级递减,最后确定目标元素位置即可。

# 最高气温-元素位置如下:

soup.select("div.t >ul.clearfix > li > p.tem")

以此类推,确定所有需要爬取的目标元素位置。

第四步:完成代码编写

requests_bs4.py :

# -*- coding: UTF-8 -*-
# 爬取静态网页工具
import requests
import time
import re
from bs4 import BeautifulSoup
import random


def get_html_text(url):
    '''
    @方法名称: 获取网页的html信息
    @中文注释: 获取网页的html信息,转换成字符串格式数据
    @入参:
        @param url str 网址
    @出参:
        @返回状态:
            @return 0 失败或异常
            @return 1 成功
        @返回错误码
        @返回错误信息
        @param rsp_text str 网页html信息
    @作    者: PandaCode辉
    @创建时间: 2023-09-05
    @使用范例: get_html_text('https://www.baidu.com/')
    '''
    try:
        if (not type(url) is str):
            return [0, "111111", "网址参数类型错误,不为字符串", [None]]

        # 浏览器用户信息列表
        user_agents = [
            'Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11',
            'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0',
            'Opera/9.25 (Windows NT 5.1; U; en)',
            'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
            'Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.5 (like Gecko) (Kubuntu)',
            'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12',
            'Lynx/2.8.5rel.1 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/1.2.9',
            'Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.7 (KHTML, like Gecko) Ubuntu/11.04 Chromium/16.0.912.77 Chrome/16.0.912.77 Safari/535.7',
            'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:10.0) Gecko/20100101 Firefox/10.0',
        ]
        # 随机获取一个浏览器用户信息
        agent = random.choice(user_agents)
        # header头信息
        headers = {
            'User-Agent': agent,
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
            'Accept-Encoding': 'gzip, deflate',
            'Connection': 'keep-alive',
            'Cache-Control': 'max-age=0',
        }
        # 代理IP地址,需要找到可用的代理ip,不然无法使用
        # proxy = {'HTTP': 'xx.xx.xx.xx:8000', 'HTTPS': 'xx.xx.xx.xx:80'}
        # response = requests.get(url, headers=headers, proxies=proxy, timeout=30)
        # 增加随机模拟浏览器访问header头信息,提高反爬网站成功率
        response = requests.get(url, headers=headers, timeout=30)
        # print(response.status_code)
        response.raise_for_status()
        response.encoding = 'utf-8'
        rsp_text = response.text
        # 返回容器
        return [1, '000000', '获取网页的html信息成功', [rsp_text]]

    except Exception as e:
        print("获取网页的html信息异常," + str(e))
        return [0, '999999', "获取网页的html信息异常," + str(e), [None]]


def spider_weather(region_code, tqyb_type):
    '''
    @方法名称: 爬取天气预报信息
    @中文注释: 根据地区代码,天气预报类型,爬取天气预报信息
    @入参:
        @param region_code str 地区代码
        @param tqyb_type str 类型(1-今天,2-近7天)
    @出参:
        @返回状态:
            @return 0 失败或异常
            @return 1 成功
        @返回错误码
        @返回错误信息
        @param rsp_dict dict 响应容器
    @作    者: PandaCode辉
    @创建时间: 2023-09-05
    @使用范例: spider_weather('101010100','1')

    天气预报网址
    http://www.weather.com.cn/weather/101010100.shtml	--北京市,近7日天气
    http://www.weather.com.cn/weather1d/101010100.shtml	--北京市,今天天气
    '''

    try:
        if (not type(region_code) is str):
            return [0, "111111", "地区代码参数类型错误,不为字符串", [None]]
        if (not type(tqyb_type) is str):
            return [0, "111112", "类型参数类型错误,不为字符串", [None]]

        url = ""
        # 类型(1-今天,2-近7天)
        if tqyb_type == '1':
            url = 'http://www.weather.com.cn/weather1d/' + region_code + '.shtml'
        elif tqyb_type == '2':
            url = 'http://www.weather.com.cn/weather/' + region_code + '.shtml'

        # UTC格式当前时区时间
        t = time.localtime()
        work_time = time.strftime("%Y-%m-%d %H:%M:%S", t)
        print('当前日期时间:' + str(work_time))
        now_day = str(work_time)[:7]
        # 根据url地址获取网页信息
        rst = get_html_text(url)
        if rst[0] != 1:
            return rst
        html_str = rst[3][0]
        # 使用BeautifulSoup解析网页数据
        soup = BeautifulSoup(html_str, "html.parser")

        # 返回容器初始化
        rsp_dict = {}
        # 类型(1-今天,2-近7天)
        if tqyb_type == '1':
            # 获取今天天气信息
            # 白天,天气情况
            tq_day_info = soup.select("div.t >ul.clearfix > li > p.wea")[0].text
            rsp_dict["tq_day_info"] = '白天,天气情况:' + tq_day_info
            print(rsp_dict["tq_day_info"])

            # 最高温度
            temperatrue_high = soup.select("div.t >ul.clearfix > li > p.tem")[0].text
            # 去除换行符
            temperatrue_high = ''.join(re.findall(r'\S', temperatrue_high))
            rsp_dict["temperatrue_high"] = '白天,最高温度:' + temperatrue_high
            print(rsp_dict["temperatrue_high"])

            # 夜间,天气情况
            tq_night_info = soup.select("div.t >ul.clearfix > li > p.wea")[1].text
            rsp_dict["tq_night_info"] = '夜间,天气情况:' + tq_night_info
            print(rsp_dict["tq_night_info"])
            # 夜间,最低温度
            temperatrue_low = soup.select("div.t >ul.clearfix > li > p.tem")[1].text
            # 去除换行符
            temperatrue_low = ''.join(re.findall(r'\S', temperatrue_low))
            rsp_dict["temperatrue_low"] = '夜间,最低温度:' + temperatrue_low
            print(rsp_dict["temperatrue_low"])
            print('===============================')
        elif tqyb_type == '2':
            # 获取近7日天气
            rsp_dict["c7day_list"] = []
            # 日期
            day_info = soup.select("div.c7d > input > input > input > ul.t.clearfix > li > h1")
            # print('日期:' + str(day_info))
            # 天气
            tq_info = soup.select("div.c7d > input > input > input > ul.t.clearfix > li > p.wea")
            # print('天气:' + str(tq_info))
            # 温度
            tem_info = soup.select("div.c7d > input > input > input > ul.t.clearfix > li > p.tem")
            # print('温度:' + str(tem_info))
            # 风力
            win_info = soup.select("div.c7d > input > input > input > ul.t.clearfix > li > p.win > i")
            # print('风力:' + str(win_info))
            # 列表存储
            for i in range(7):
                temp_dict = {}
                # 日期
                temp_dict["day_info"] = '日期:' + now_day + '-' + str(day_info[i].text)
                print(temp_dict["day_info"])
                # 天气
                temp_dict["tq_info"] = '天气:' + str(tq_info[i].text)
                print(temp_dict["tq_info"])
                # 温度
                # 去除换行符
                temperatrue = ''.join(re.findall(r'\S', str(tem_info[i].text)))
                temp_dict["tem_info"] = '温度:' + temperatrue
                print(temp_dict["tem_info"])
                # 风力
                temp_dict["win_info"] = '风力:' + str(win_info[i].text)
                print(temp_dict["win_info"])
                # 添加到列表
                rsp_dict["c7day_list"].append(temp_dict)
                print('===============================')
        # 返回容器
        return [1, '000000', '爬取天气预报信息成功', [rsp_dict]]

    except Exception as e:
        print("爬取天气预报信息异常," + str(e))
        return [0, '999999', "爬取天气预报信息异常," + str(e), [None]]


# 主方法
if __name__ == '__main__':
    # 101010100 - 北京市
    # 爬取天气预报-今天
    rst1 = spider_weather('101010100', '1')
    rsp_dict1 = rst1[3][0]
    print(rsp_dict1)
    # 爬取天气预报-近7天
    rst2 = spider_weather('101010100', '2')
    rsp_dict2 = rst2[3][0]
    print(rsp_dict2)

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

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

相关文章

6、Spring之依赖注入源码解析(上)

依赖注入底层原理流程图: Spring中Bean的依赖注入原理| ProcessOn免费在线作图,在线流程图,在线思维导图 Spring中到底有几种依赖注入的方式? 首先分两种: 手动注入自动注入手动注入 在XML中定义Bean时,就是手动注入,因为是程序员手动给某个属性指定了值。 <bean n…

系统内存的探测

lab2 系统内存的探测 参考博客 主要涉及操作系统的物理内存管理。 操作系统为了使用内存&#xff0c;还需高效地管理内存资源。 这里我们会了解并且自己动手完成一个简单的物理内存管理系统。实验目的 理解基于段页式内存地址的转换机制 理解页表的建立和使用方法 理解物理内…

Python之线程Thread(一)

一、什么是线程 线程(Thread)特点: 线程(Thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位;一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线;…

【JavaEE】_CSS引入方式与选择器

目录 1. 基本语法格式 2. 引入方式 2.1 内部样式 2.2 内联样式 2.3 外部样式 3. 基础选择器 3.1 标签选择器 3.2 类选择器 3.3 ID选择器 4. 复合选择器 4.1 后代选择器 4.2 子选择器 4.3 并集选择器 4.4 伪类选择器 1. 基本语法格式 选择器若干属性声明 2. 引入…

c语言练习47:模拟实现strncat

模拟实现strncat 代码&#xff1a; #include<stdio.h> #include<assert.h> char* my_strncat(char* dest, const char* src, size_t num) {assert(dest ! NULL && src ! NULL);char* ret dest;while (num--) {*dest *src;}return ret; } int main() {ch…

【Linux】进程间通信(匿名管道、命名管道、共享内存等,包含代码示例)

进程间通信 前言正式开始理解进程间通信一些标准管道原理管道演示匿名管道代码演示原理进程池管道大小 命名管道演示代码分配消息例子 systemV共享内存共享内存流程获取key值shm的创建shm的删除关联去关联完整流程演示开始通信 systemV 消息队列基于对共享内存的理解几个概念 前…

mysql的索引语法

创建索引 CREATE [ UNIQUE | FULLTEXT ] INDEX index_name ON table_name ( index_col_name,... ) ; 普通索引 name字段为姓名字段&#xff0c;该字段的值可能会重复&#xff0c;为该字段创建索引。 CREATE INDEX idx_user_name ON tb_user(name); 唯一索引 phone手机…

我的网站每个月给我带来了6W美元收入

2014 年,我开始在东京寻找软件工程工作。 但我不想要任何旧工作。我想要一个——因为没有更好的术语——实际上很好的。 因为我听说过一些关于日本科技行业的可怕事情。过度劳累的故事。低工资。令人畏惧的日本“黑公司”。 但尽管有这些故事,我相信也有优秀的科技公司。于…

windows各种运行库一次性解决方法

3DM游戏运行库合集离线安装包&#xff08;1G&#xff09; - 『精品软件区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cnhttps://www.52pojie.cn/thread-1308401-1-1.html新的电脑系统上,运行一个软件,报缺少.dll,不是少了.net 就是少了 directx,vc runtime,下载…

黑马头条学习中的一些问题

1.在day3&#xff0c;上传图片时候&#xff0c;有一个错误&#xff0c;我完成代码逻辑后&#xff0c;启动进行上传时&#xff0c;发现报错了&#xff0c;报的是空指针异常 开始我认为微服务之间使用threadlocal是无法进行数据共享的&#xff0c;但是我有顺着老师讲的思路走了一…

Navicat15 /16 已连接数据库密码解密

前言 相信你会遇到使用navicat忘记已连接数据密码的问题吧&#xff01;实在是&#xff0c;密码太多容易忘记&#xff01;&#xff01;&#xff01; 感谢大佬as_dmy的文章如何查看navicat已连接数据库密码&#xff0c;然后才有了此文&#xff01; 1.0版本需要手动查看导出的co…

GET 和 POST请求的区别是什么

GET和POST是HTTP请求的两种基本方法&#xff0c;要说它们的区别&#xff0c;接触过WEB开发的人都能说出一二。 最直观的区别就是GET把参数包含在URL中&#xff0c;POST通过request body传递参数。 你轻轻松松的给出了一个“标准答案”&#xff1a; GET在浏览器回退时是无害的…

互联网真实赚钱平台有哪些?分享六大类正规靠谱的线上平台

互联网已经和我们的生活密不可分&#xff0c;我们每天都穿梭在网络的世界里&#xff0c;感受着信息的洪流&#xff0c;但同时也感受到了贫富差距的日益拉大。然而&#xff0c;互联网的蓬勃发展也为我们提供了一个机会——通过在线平台赚取真实的收入。 尽管在这个领域中存在着许…

QUIC协议连接详解(二)

目录 一&#xff1a;RTT解释 二&#xff1a;QUIC 1-RTT连接 三&#xff1a;QUIC 0-RTT连接 一&#xff1a;RTT解释 在介绍QUIC协议的连接之前先科普一下什么是RTT。RTT是Round-Trip Time的英文缩写&#xff0c;翻译过来就是一趟来回的时间即往返时延。时间计算即从发送方发送…

工作每天都在用的 DNS 协议,你真的了解么?

♥ 前 言 我们经常访问一些网址的时候&#xff0c;浏览器里输入类似于 www.baidu.com 这样的地址&#xff0c;那么在浏览器里输入这个地址---> 百度服务器给我们返回这个百度的页面&#xff0c;中间的过程是什么样的呢&#xff1f; 带着这个问题&#xff0c;我们一起来解…

答题题库模拟考试流量主小程序源码开发

一款专门为练题开发的题库答题考试模拟小程序&#xff0c;适用于多种用户群体&#xff0c;驾照考题、各种职业考试、英语四六级等等。接入流量主功能&#xff0c;运营方可以更灵活的配置收益方式。 小程序核心功能介绍&#xff1a; 1、多题型支持&#xff0c;判断题、单选题…

记一次Nacos线程数飙升排查

近日有个项目用到了Nacos做注册中心。运行一段时间发现Nacos服务的线程数达到了1k。这肯定是不正常的。 环境&#xff1a; Nacos-server 2.2.3docker-compose编排部署 nacos:image: "nacos/nacos-server:latest"environment:- JAVA_OPTS-XX:MetaspaceSize128m -XX:…

PLC-Recorder离线分析软件Ana里为什么不能显示变量的编号?

在PLC-Recorder在线软件里&#xff0c;大家可以在曲线上找到变量的编号&#xff08;由通道编号、变量类型、同类型序号组成&#xff09;。这个编号也是各软件识别变量的唯一标识。在变量和PLC很多时&#xff0c;可以方便地找到对应的PLC&#xff0c;如下&#xff1a; 有朋友问&…

【QGIS】Openstreetmap获取路网数据

目录 一、从Openstreetmap获取路网数据 1.1 根据城市名获取对应ID 1.2 根据城市ID获取路网数据 二、下载安装QGIS 2.1 下载QGIS 2.2 安装QGIS 2.3 页面语言设置 三、将获取到的osm文件拖入QGIS 一、从Openstreetmap获取路网数据 在大多数研究中&#xff0c;经常使用到的…

类欧笔记存档

电子版&#xff1a;https://blog.csdn.net/zhangtingxiqwq/article/details/132718582