python爬虫:从12306网站获取火车站信息

代码逻辑

  • 初始化 (init 方法):
    • 设置请求头信息。
    • 设置车站版本号。
  • 同步车站信息 (synchronization 方法):
    • 发送GET请求获取车站信息。
    • 返回服务器响应的文本。
  • 提取信息 (extract 方法):
    • 从服务器响应中提取车站信息字符串。
    • 去掉字符串末尾的多余字符。
  • 处理信息 (process 方法):
    • 提取并处理车站信息。
    • 打印车站总数。
    • 创建一个新的车站字典,只包含所需的字段。
    • 调用 save_station 方法保存车站信息。
  • 保存车站信息 (save_station 方法):
    • 将车站信息保存到本地JSON文件。
  • 查找含有关键词的车站 (find_keyword_station 静态方法):
    • 从本地文件加载车站信息。
    • 根据关键词查找符合条件的车站。
  • 查找以指定字符结尾的车站 (find_stations_with_last_char 方法):
    • 从本地文件加载车站信息。
    • 找出以指定字符结尾的车站名称。
    • 调用 save_matching_stations 方法保存结果。
  • 保存匹配的车站 (save_matching_stations 方法):
    • 将匹配的车站信息保存到本地JSON文件。
  • 查找所在城市的车站 (find_stations_in_city 方法):
    • 从本地文件加载车站信息。
    • 找出所在城市为指定城市的车站。
  • 主程序入口 (if name == "main " 块):
    • 实例化 Station 类。
    • 调用 process 方法处理车站信息。
    • 调用 find_stations_with_last_char 方法查找以特定字符结尾的车站。
    • 调用 find_keyword_station 方法查找含有关键词的车站。
    • 调用 find_stations_in_city 方法查找所在城市的车站。

完整代码

python 复制代码
import json
import re
import requests

# 定义车站信息的URL
URL_STATION_NAME = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js'

class Station:
    def __init__(self):
        # 设置请求头
        self.headers = {
            'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                          "Chrome/123.0.0.0 Safari/537.36"
        }

        # 获取车站版本号
        self.version = '1.9320'

    def synchronization(self):
        # 发送GET请求获取车站信息
        response = requests.get(URL_STATION_NAME, headers=self.headers, params={
            "station_version": self.version
        })
        return response.text

    def extract(self):
        # 提取响应中的车站信息
        response = self.synchronization()
        response = response.replace("var station_names =", '').strip()
        return response[:-2]  # 去掉末尾的多余字符

    def process(self):
        # 处理提取的数据
        response = self.extract()
        response = re.findall(r'@(.*?)\|\|\|', response)
        print(f'共有{len(response)}个车站')
        response = [i.split("|") for i in response]

        # 创建一个新的车站字典,只包含所需的字段
        station_dict = []
        for item in response:
            station_info = {
                "车站名": item[1],
                "车站代码": item[2],
                "车站编号": item[5],
                "所在城市": item[7],
                "城市编号": item[6]
            }
            station_dict.append(station_info)

        self.save_station(station_dict)
        
        return station_dict

    def save_station(self, station_dict):
        # 将车站信息保存到本地文件
        with open('resource/station_dict.json', 'w', encoding='utf-8') as f:
            json.dump(station_dict, f, ensure_ascii=False, indent=4)

    @staticmethod
    def find_keyword_station(keyword, _type='station'):
        # 查找含有keyword的站名
        with open('resource/station_dict.json', 'rt', encoding='utf-8') as f:
            station_dict = json.load(f)
        
        if _type == 'station':
            response = [item for item in station_dict if keyword.lower() in item["车站名"].lower()]
        elif _type == 'code':
            response = [item for item in station_dict if keyword.lower() in item["车站代码"].lower()]
        else:
            response = []

        return response
    
    def find_stations_with_last_char(self, char):
        # 查找所有字典的key里最后一个字是指定字符的站名,并保存结果到JSON文件
        with open('resource/station_dict.json', 'rt', encoding='utf-8') as f:
            station_dict = json.load(f)
        
        # 使用列表推导式来找到符合要求的站名
        matching_stations = [item for item in station_dict if item['车站名'].endswith(char)]
        
        # 保存结果到JSON文件
        self.save_matching_stations(matching_stations, char)
        
        return matching_stations

    def save_matching_stations(self, matching_stations, char):
        # 将车站信息保存到本地文件
        filename = f'resource/stations_with_last_char_{char}.json'
        with open(filename, 'w', encoding='utf-8') as f:
            json.dump(matching_stations, f, ensure_ascii=False, indent=4)

    def find_stations_in_city(self, city_name):
        # 查找所在城市为指定城市的车站
        with open('resource/station_dict.json', 'rt', encoding='utf-8') as f:
            station_dict = json.load(f)
        
        # 使用列表推导式来找到符合要求的站名,并排除不需要的字段
        matching_stations = [
            {k: v for k, v in item.items() if k not in ['所在城市', '城市编号']}
            for item in station_dict if city_name.lower() in item['所在城市'].lower()
        ]
        
        return matching_stations

# 主程序入口
if __name__ == "__main__":
    station = Station()
    station.process()
    
    result = station.find_stations_with_last_char('东')
    print(f"找到 {len(result)} 个以 '东' 结尾的站名")
    
    result = station.find_stations_with_last_char('西')
    print(f"找到 {len(result)} 个以 '西' 结尾的站名")
    
    result = station.find_stations_with_last_char('南')
    print(f"找到 {len(result)} 个以 '南' 结尾的站名")
    
    result = station.find_stations_with_last_char('北')
    print(f"找到 {len(result)} 个以 '北' 结尾的站名")
    
    # 查找含有'湛江'的站名
    keyword = '湛江'
    result = station.find_keyword_station(keyword, _type='station')
    print(result)
    
    # 查找所在城市为'湛江'的车站
    city_name = '湛江'
    result = station.find_stations_in_city(city_name)
    print(f"找到 {len(result)} 个位于 '{city_name}' 的车站:")
    print(result)

运行结果

本文参考了这个项目,在此表示感谢,但由于该项目需要配置flask,笔者对此并不熟悉,于是自己抽取出查询车站的代码并完善了相关功能,不再需要其他配置。

相关推荐
程序喵大人8 分钟前
【C++进阶】STL容器与迭代器 - 01 STL 容器先解决元素放在哪里
开发语言·c++·stl
cui_ruicheng26 分钟前
Python从入门到实战(十六):多进程编程
开发语言·python
wdfk_prog2 小时前
嵌入式面试真题第 15 题:不可恢复异常后的通用崩溃快照、调用栈保存与离线分析架构
linux·开发语言·面试·架构
_Jimmy_2 小时前
FastAPI + SQLAlchemy全局事务管理
python·fastapi
晴空了无痕2 小时前
从 Go 基础到 K8s:一条可落地的 Go 服务端成长路线
开发语言·后端·golang·kubernetes
用户8356290780512 小时前
如何使用 Python 在 Excel 中添加、编辑和删除超链接
后端·python
神明不懂浪漫2 小时前
【第五章】Java中的继承与多态
java·开发语言
神州世通3 小时前
解密企业通信安全防线:Avaya Aura 三层安全架构深度解析
开发语言·php
AC赳赳老秦4 小时前
企业工商公开信息采集分析:OpenClaw 批量查询企业工商信息,生成企业画像报告
大数据·开发语言·python·自动化·php·deepseek·openclaw
qq_2518364574 小时前
基于java Web 动漫视频网站毕业论文
java·开发语言·前端