102302138 林楚涵 作业2

news/2025/11/11 19:09:58/文章来源:https://www.cnblogs.com/lch1103/p/19211338

🌦️ 第二次爬虫作业实录|天气 + 股票 + 大学榜


作业①:在中国气象网(http://www.weather.com.cn)给定城市集的7日天气预报,并保存在数据库。

① 核心代码与运行截图

点击查看代码
import sqlite3, urllib.request, bs4, redb = sqlite3.connect('w.db')
db.execute('create table if not exists t(c,d,w,m)')
db.execute('delete from t')head = {'User-Agent':'Mozilla/5.0'}
code = {'北京':'101010100','上海':'101020100','广州':'101280101','深圳':'101280601'}for city in code:url = f'http://www.weather.com.cn/weather/{code[city]}.shtml'html = bs4.BeautifulSoup(urllib.request.urlopen(urllib.request.Request(url, headers=head)).read(), 'lxml')for li in html.select('ul.t.clearfix li')[:7]:d = li.h1.text.strip()w = li.find('p','wea').texttem = li.find('p','tem')hi = tem.span.text if tem.span else '—'lo = tem.i.text if tem.i else '—'db.execute('insert into t values(?,?,?,?)', (city,d,w,f'{hi}/{lo}'))
db.commit()for r in db.execute('select * from t order by c,d'):print(*r)
db.close()
* *

3fa07cb0a90e940940cd3664b6c789f3
*

② 作业心得

这段代码的核心思路是“构造请求→解析页面→提取数据→入库→展示”。首先建立 SQLite 数据库并清空历史数据;随后用伪装的 User-Agent 头,按“城市-编码”字典循环拼接中国天气网 7 日预报 URL,通过 urllib 拉取 HTML 后交给 BeautifulSoup 解析;针对返回的 7 个

  • 节点,依次提取日期、天气描述及高低温字符串,拼成“高/低”格式,将城市、日期、天气、温度四元组写入数据库;最后统一提交事务并按城市、日期排序输出,实现轻量级、单文件、零依赖的天气爬取与持久化。

    ③ Gitee文件夹链接

    https://gitee.com/forest-stream-whisper/2025_crawl_project/blob/master/%E4%BD%9C%E4%B8%9A2/%E4%BD%9C%E4%B8%9A2/1.db


    作业②:用requests和BeautifulSoup库方法定向爬取股票相关信息,并存储在数据库中。

    ① 核心代码与运行截图

    **

    点击查看代码
    import requests, json, time, csv, osdef get_stock_data(page):url = "http://69.push2.eastmoney.com/api/qt/clist/get"params = {"pn": page, "pz": 20, "po": 1, "np": 1,"ut": "bd1d9ddb00efe4882cddb8fe999b62f7c","fltt": 2, "invt": 2, "fid": "f3","fs": "m:0+f:8,m:1+f:8","fields": "f12,f14,f2,f3,f4,f5,f6,f7","_": int(time.time() * 1000)}headers = {"User-Agent": "Mozilla/5.0","Referer": "http://quote.eastmoney.com/"}resp = requests.get(url, params=params, headers=headers)data = json.loads(resp.text)return data["data"]["diff"] if data.get("data") else []def print_and_save_stocks(stocks, start_idx, csv_path, is_first):if is_first:print("序号  代码      名称        最新价    涨跌幅    涨跌额      成交量(万手)  成交额(亿)   振幅")for i, stock in enumerate(stocks, start_idx):code = stock.get("f12", "")name = stock.get("f14", "")price = round(stock.get("f2", 0.0), 2)chg_pct = round(stock.get("f3", 0.0), 2)chg_amt = round(stock.get("f4", 0.0), 2)vol = round(stock.get("f5", 0) / 10000, 2)amt = round(stock.get("f6", 0.0) / 1e8, 2)amp = round(stock.get("f7", 0.0), 2)print(f"{i:2d}  {code:6s}    {name:<8s} {price:6.2f}  {chg_pct:6.2f}%  {chg_amt:7.2f}  {vol:12.2f}  {amt:10.2f}  {amp:6.2f}%")os.makedirs(os.path.dirname(csv_path), exist_ok=True)headers = ["序号", "代码", "名称", "最新价", "涨跌幅(%)", "涨跌额", "成交量(万手)", "成交额(亿)", "振幅(%)"]with open(csv_path, "a", newline="", encoding="utf-8-sig") as f:writer = csv.DictWriter(f, fieldnames=headers)if is_first:writer.writeheader()for i, s in enumerate(stocks, start_idx):writer.writerow({"序号": i, "代码": s.get("f12"), "名称": s.get("f14"),"最新价": round(s.get("f2", 0), 2),"涨跌幅(%)": round(s.get("f3", 0), 2),"涨跌额": round(s.get("f4", 0), 2),"成交量(万手)": round(s.get("f5", 0) / 10000, 2),"成交额(亿)": round(s.get("f6", 0) / 1e8, 2),"振幅(%)": round(s.get("f7", 0), 2)})def main():csv_path = "股票/创新股数据/创新股股票数据.csv"for page in range(1, 3):print(f"\n====== 第{page}页数据 ======")stocks = get_stock_data(page)if stocks:print_and_save_stocks(stocks, (page - 1) * 20 + 1, csv_path, page == 1)print(f"第{page}页数据已保存到 {csv_path}")else:print("未获取到数据")time.sleep(1)if __name__ == "__main__":main()
    
    *

    c1037597e61897095d15cfb3b1f6f5fb

    084a866dfb159e4001322a650c63734c

    ② 作业心得

    整段代码以东方财富网公开 JSONP 接口为切入口,先拼接带分页、字段过滤和时间戳的动态 URL,再用 Session 伪装浏览器请求并解析返回 JSON,批量提取股票代码、名称、最新价等八项关键指标,实时控制台对齐打印的同时追加写入 CSV,通过分页循环与延迟机制完成 40 条创新股数据的完整落盘,全程用函数分工实现“请求-解析-输出-存储”流水线,既避免重复建表又保证中断续写,将抓包、参数构造、异常兜底和落盘细节封装成可复用的轻量级框架。

    ③ Gitee文件夹链接

    https://gitee.com/forest-stream-whisper/2025_crawl_project/blob/master/%E4%BD%9C%E4%B8%9A2/%E4%BD%9C%E4%B8%9A2/2.csv

    作业③:爬取中国大学2021主榜(https://www.shanghairanking.cn/rankings/bcur/2021)所有院校信息,并存储在数据库中,同时将浏览器F12调试分析的过程录制Gif加入至博客中。

    ① 核心代码与运行截图

    *

    点击查看代码
    import re
    import requests
    import sqlite3
    from datetime import datetime# 基础配置
    db_name = "2021_univ_rank.db"
    target_url = "https://www.shanghairanking.cn/_nuxt/static/1762223212/rankings/bcur/2021/payload.js"
    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
    }# 省市、学校类型编码映射
    province_code = {'k': '江苏', 'n': '山东', 'o': '河南', 'p': '河北', 'q': '北京', 'r': '辽宁','s': '陕西', 't': '四川', 'u': '广东', 'v': '湖北', 'w': '湖南', 'x': '浙江','y': '安徽', 'z': '江西', 'A': '黑龙江', 'B': '吉林', 'D': '上海', 'F': '福建','E': '山西', 'H': '云南', 'G': '广西', 'I': '贵州', 'J': '甘肃', 'K': '内蒙古','L': '重庆', 'N': '天津', 'O': '新疆', 'az': '宁夏', 'aA': '青海', 'aB': '西藏'
    }
    category_code = {'f': '综合', 'e': '理工', 'h': '师范', 'm': '农业', 'S': '林业'
    }# 正则表达式:提取学校名称、类型、省市、分数
    rank_pattern = re.compile(r'univNameCn:"(?P<name>[^"]+)",.*?'r'univCategory:(?P<cat>[^,]+),.*?'r'province:(?P<prov>[^,]+),.*?'r'score:(?P<score>[^,]+),',re.S
    )def clean_str(s):return s.strip().strip('"')def init_database():conn = sqlite3.connect(db_name)cursor = conn.cursor()# 创建表结构cursor.execute('''CREATE TABLE IF NOT EXISTS univ_rank_2021 (id INTEGER PRIMARY KEY AUTOINCREMENT,ranking INTEGER NOT NULL,school TEXT NOT NULL,province TEXT NOT NULL,category TEXT NOT NULL,total_score FLOAT NOT NULL,crawl_time TEXT NOT NULL)''')conn.commit()conn.close()print("数据库初始化完成")def save_data(school_list):crawl_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')conn = sqlite3.connect(db_name)cursor = conn.cursor()# 批量插入数据(按排名顺序)for i, (school, prov, cat, score) in enumerate(school_list, 1):cursor.execute('''INSERT INTO univ_rank_2021 (ranking, school, province, category, total_score, crawl_time)VALUES (?, ?, ?, ?, ?, ?)''', (i, school, prov, cat, score, crawl_time))conn.commit()conn.close()def get_univ_ranking():resp = requests.get(target_url, headers=headers)resp.encoding = resp.apparent_encoding  # 自动适配编码content = resp.textrank_list = []# 正则匹配提取每条学校数据for match in rank_pattern.finditer(content):# 提取原始字段并清理school_name = clean_str(match.group('name'))cat_raw = clean_str(match.group('cat'))prov_raw = clean_str(match.group('prov'))score_raw = clean_str(match.group('score'))# 映射编码到实际省市和类型province = province_code.get(prov_raw, '其他')category = category_code.get(cat_raw, '其他')# 分数转换为浮点数(跳过无效分数)try:score = float(score_raw)except:continue# 过滤空学校名称,添加到列表if school_name:rank_list.append((school_name, province, category, score))# 按总分降序排序rank_list.sort(key=lambda x: x[3], reverse=True)return rank_listdef main():init_database()univ_data = get_univ_ranking()# 打印爬取结果(格式化输出)print("\n排名  学校                 省市      类型    总分")print("-" * 50)for i, (school, prov, cat, score) in enumerate(univ_data, 1):print(f"{i:<4} {school:<20} {prov:<8} {cat:<6} {score:.1f}")# 保存数据到数据库save_data(univ_data)print(f"\n爬取完成!共{len(univ_data)}所大学数据已保存到{db_name}")if __name__ == "__main__":main()
    

    0cbef4a25ee705420a05ed1e802093c2

    9

    ② 作业心得

    这段代码首先通过 requests 库向目标 API 发起请求,获取包含排名信息的 JavaScript 数据文件;接着利用正则表达式从响应内容中提取学校名称、省市编码、类型编码及总分等关键信息,再通过预设的编码映射表将省市和类型编码转换为中文名称,并对分数进行格式转换和过滤;之后按总分降序对提取的学校数据排序,得到排名结果;最后初始化 SQLite 数据库,创建用于存储排名数据的表,将处理后的学校信息(含排名、名称、省市、类型、总分及爬取时间)批量插入数据库,并打印展示爬取结果。整体流程实现了从网络数据获取到本地结构化存储的闭环

    ③ Gitee文件夹链接

    https://gitee.com/forest-stream-whisper/2025_crawl_project/blob/master/%E4%BD%9C%E4%B8%9A2/%E4%BD%9C%E4%B8%9A2/3.db

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

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

    相关文章

    如何在 Windows 中使用 Kimi CLI(PowerShell 补充版)

    字数 334,阅读大约需 2 分钟如何在 Windows 中使用 Kimi CLI(PowerShell 版)说明:本教程适用于 PowerShell 环境。如需在 WSL (Windows Subsystem for Linux) 中安装,请参考其他相关教程。一、安装 uv(包管理器)…

    【计算机网络表格图表解析】网络体系结构、资料链路层、网络层、传输层、应用层、网络安全、故障排查

    pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

    PWM妙用:解锁LED亮度调节与呼吸灯的LuatOS开发之旅

    在嵌入式开发的精彩世界里,PWM技术有着举足轻重的地位。本次,我们将聚焦于PWM的经典应用——LED亮度控制及呼吸灯效果的实现。通过LuatOS开发环境,详细展示如何运用PWM功能,让开发者能够迅速掌握这一实用技能,开启…

    主子式与顺序主子式

    主子式 (Principal Minor)是线性代数中一个与矩阵相关的重要概念。 定义 对于一个nnn cross n 𝑛𝑛的方阵 Abold cap A 𝐀 ,它的 kk 𝑘阶主子式是指从矩阵中选取相同的行号和列号构成的一个 kkk cross k �…

    python项目跟练 外星人入侵 01 3个位置

    3个位置 1、游戏屏幕大小 2、飞船图片大小 3、飞船在游戏屏幕中位置游戏屏幕大小 # 将屏幕大小设置存到一个单独设置类中 self.screen_width = 1000 # 定义屏幕 宽xx像素 self.screen_height = 800 # 定义屏幕 高xx…

    ONES 重磅升级|全新内核,深度可配置,适配复杂业务流

    ONES 于近期完成创业十年来最大范围内核代际升级。深度灵活的自定义引擎,完善的开放平台体系,AI 友好的数据交互架构。此次内核升级的首批上层功能已正式发布。 此次 ONES Project 全新升级,围绕工作项信息管理与多…

    类的继承

    类的继承子类: public class teacher extends stu{}父类 public class stu {public String name="111";public void say(){System.out.println("shuohua");} }使用 public class Main {public st…

    CUDA安装注意事项

    参考网站:https://blog.csdn.net/weixin_52677672/article/details/135853106?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522f12aadfcb1121e89732052c8440ee6c5%2522%252C%2522scm%2522%253A%252220140…

    豆包Seed-Coder编程能力小试

    豆包Seed-Coder编程能力小试背景 最近字节发布doubao-seed-code-preview-251028模型面向Agentic编程任务深度优化 - 支持256K长上下文,让模型轻松处理长代码文件、多模块依赖等复杂场景,更好支持端到端自主编程…

    数据类型 标识符 键盘录入

    数据类型 标识符 键盘录入数据类型 标识符 键盘录入 数据类型 基本数据类型 ![基本数据类型](/Users/eefile/Documents/截屏2025-11-11 17.37.18.png) 代码测试 public class num { public static void main(String[]…

    102302145 黄加鸿 数据采集与融合技术作业2

    作业2目录作业2作业①1)代码与结果2)心得体会3)Gitee链接作业②1)代码与结果2)心得体会3)Gitee链接作业③1)代码与结果F12调试分析Gif2)心得体会3)Gitee链接作业① 1)代码与结果 中国气象网在之前任务中已经…

    详细介绍:Spring Boot

    pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

    echarts获取坐标上的点距离顶部底部高度

    const height = echarts_instance.getHeight()const max_distance = (max_y - y_value) / (max_y - min_y) * height;const min_distance = (y_value - min_y) / (max_y - min_y) * height;

    K8S(九)—— Kubernetes持久化存储深度解析:从Volume到PV/PVC与StorageClass动态存储 - 教程

    pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

    JAVA 随机函数

    目录1. 日常开发(非安全场景):ThreadLocalRandom(推荐)2. 单线程/简单场景:Random3. 安全场景(如密码、Token生成):SecureRandom4. Java 8+ 流式处理:Random 结合流关键总结 在 Java 中生成随机数的“靠谱”…

    GPIO 也是一个接口,还有 QEMU GPIODEV 和 GUSE - 指南

    pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

    CF1327F AND Segments

    经典问题。 首先拆位,那么限制变成强制一段全为 \(1\),或者强制一段存在 \(0\),先把第一个限制填完,再考虑第二个限制。 然后对于第二个条件,将包含关系给干掉,那么按照 \(l\) 排序后 \(r\) 也是递增的,考虑容斥…

    Air780EPM系列低功耗模组USB设计进阶:硬件要点与LuatOS API开发赋能

    本文将以Air780EPM系列低功耗模组为对象,探讨USB接口硬件设计的关键要点,并介绍LuatOS高效开发API的赋能作用。旨在帮助开发者避开常见设计误区,快速实现稳定可靠的USB应用开发目标。 在设计USB接口时,不少刚接触嵌…