草庐IT

抓取每路公交的具体信息

Aurora* 2023-03-28 原文

@

1.抓取查询路径:

抓取 https://lanzhou.8684.cn/ 中以数字开头的公交线路的查询路径。

<div class="list">
    <a href="/list1">1</a>
    <a href="/list2">2</a>
    <a href="/list3">3</a>
    <a href="/list4">4</a>
    <a href="/list5">5</a>
    <a href="/list6">6</a>
    <a href="/list7">7</a>
    <a href="/list8">8</a>
    <a href="/list9">9</a>
</div>

这里所看到的 href 属性值,加上 https://lanzhou.8684.cn/ 就是将来的查询地址。

以此抓取所有的数字开头的公交线路。:

https://lanzhou.8684.cn/listX

其中末尾的 X 表示 数字 1 ~ 9
如:https://lanzhou.8684.cn/list1

2.拼接每路公交的线路链接:

抓取 https://lanzhou.8684.cn/listX中每路公交的线路链接。

<div class="list clearfix">
	<a href="/x_24f5dad9" title="兰州1路公交车路线">1路</a>
	<a href="/x_8234e473" title="兰州10路公交车路线">10路</a>
	<a href="/x_26ecc8ae" title="兰州11路公交车路线">11路</a>
	<a href="/x_27905c0e" title="兰州12路公交车路线">12路</a>
	<a href="/x_9023980b" title="兰州13路公交车路线">13路</a>
	<a href="/x_be53b447" title="兰州14路公交车路线">14路</a>
	<a href="/x_5a54ae14" title="兰州15路公交车路线">15路</a>
	<a href="/x_968a4331" title="兰州16路公交车路线">16路</a>
	<a href="/x_4177a33a" title="兰州17路公交车路线">17路</a>
	<a href="/x_bfe4a3eb" title="兰州18路公交车路线">18路</a>
	...
</div>

这里所看到的 href 属性值,加上 https://lanzhou.8684.cn/ 就是每路公交的线路链接。
如:https://lanzhou.8684.cn/x_24f5dad9

以此抓取所有线路链接。:

3.抓取每路公交的具体信息

兰州9路公交车路线[市区线路]
运行时间:西关什字6:00-22:30|晟地兰州汽配城6:00-21:40
参考票价:无人售票车,1.0元一票制,支持交联IC卡/云闪付/微信/支付宝/万支付/翼支付/美团支付等多种支付方式
公交公司:兰州公交集团第五客运公司

4. 实现代码

# author:Aurora
# Datetime:2022-6-24 11:41:00
""" 
抓取每路公交的具体信息
title:
run_time:
tickets_price:
bus_company:
"""
# 所有库
import requests
import re
from bs4 import BeautifulSoup
import pandas as pd
import os
import time

# 进度条
def progress():
    for i in range(101):
        time.sleep(0.05)
        print(f"\r进度:{'-'*i} {i}%", end='')
    return 200

# 获取信息函数
def get_every_raod_bus_info():
    url = "https://lanzhou.8684.cn/"
    # 伪造header
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.124 Safari/537.36 Edg/102.0.1245.44"
    }
    response = requests.get(url=url, headers=headers)
    soup = BeautifulSoup(response.text, features='lxml')
    """ 
    兰州公交线路:
    1. 以数字开头
    2. 以汉字/字母开头
    3. 线路分类

    都在三个类为pl10的标签中,获取它们
    """
    # 获取第一个pl10也就就是以数字开头,
    items = soup.select('.pl10')[0]
    # 获取list
    list = items.select('.list')
    list = list[0] if len(list) > 0 else ''
    # 获取list里面的a标签
    a = list.select('a')
    # 获取属性href:['/list','/list2',..,'/list9'],listX,X代表不同数字开头的公家车,1,11,12,119,110路等公交车
    hrefs = [i['href'] for i in a]
    link = "https://lanzhou.8684.cn/"
    # 1. 拼接查询地址https://lanzhou.8684.cn/listX,X[1-9],就是每个数字开头的公公交车
    # 输入数字开头的公交线路(1-9)
    n1 = eval(input("请输入以数字开头的公车(1-9):"))
    links = []
    links.append(link+hrefs[n1-1])
    print(links)

    # 2. 拼接每路公交的线路链接
    """ 
    格式如下
    1:https://lanzhou.8684.cn/x_24f5dad9
    10:https://lanzhou.8684.cn/x_8234e473
    11:https://lanzhou.8684.cn/x_26ecc8ae
    ...
    https://lanzhou.8684.cn/XXXX
    """
    # 每路公交的链接列表
    road_list = []
    # 链接前缀
    all_road_prefix = "https://lanzhou.8684.cn"
    for url in links:
        response = requests.get(url, headers=headers)
        soup = BeautifulSoup(response.text, features='lxml')
        # 获取list
        lists = soup.select('.list')
        list = lists[0] if len(lists) > 0 else ''
        # 获取里面的a标签
        a = list.select('a')
        for i in a:
            # 取属性href然后拼接后存入到road_list
            road_list.append(all_road_prefix+i['href'])
    print(road_list)
    # 3. 获取每路公交的信息
    """ 
    title:
    run_time:
    tickets_price:
    bus_company:
    last_updated:
    """
    road_info_dic = {}
    title_list = []
    run_time_list = []
    ticket_price_list = []
    bus_company_list = []
    last_updated_list = []
    n = 1
    for road_url in road_list:
        response = requests.get(road_url, headers=headers)
        soup = BeautifulSoup(response.text, features='lxml')
        # 获取信息(返回的是列表)
        info = soup.select('.info')
        # print(info)
        # 判断是否为空
        info = info[0] if len(info) > 0 else ''
        # 获取所有span标签
        spans = info.select('span')
        """
        [<span aria-label="兰州1路公交车路线" tabindex="0">兰州1路公交车路线</span>, <span tabindex="0">公交公司:</span>, <span tabindex="0">最后更新:2022-06-24</span>]
        """
        # 标题:兰州1路公交车路线
        title = spans[0].text
        # 获取所有a标签
        a = info.select('a')
        """
        [<a aria-label="市区线路,按回车键查看全部市区线路" class="category" href="/line1">[市区线路]</a>, <a aria-label="兰州公交集团第一客运公司,按回车键查看全部兰州公交
        集团第一客运公司运营的公交线路。" href="/g21" title="兰州公交集团第一客运公司">兰州公交集团第一客运公司</a>]
        """
        # 发现副标题category在第一个a标签里面
        # 副标题:[市区线路]
        categorys = a[0].text
        # 拼接总标题
        # 总标题: 兰州9路公交车路线[市区线路]
        titles = title+categorys
        title_list.append(titles)
        print(titles)
        # 获取所用信息描述:ul标签
        bus_descs = info.select('.bus-desc')
        bus_desc = bus_descs[0] if len(bus_descs) > 0 else ''
        # 获取所有li标签(信息都在li中)如下:
        lis = bus_desc.select('li')
        # print(lis)
        """
        [<li tabindex="0">运行时间:兰州西站5:55-00:00|兰州车站5:40-00:00</li>, <li tabindex="0">参考票价:无人售票车,1.0元一票制,支持交联IC卡/云闪付/微信/支付宝/万支付/
        翼支付/美团支付等多种支付方式</li>, <li><span tabindex="0">公交公司:</span><a aria-label="兰州公交集团第一客运公司,按回车键查看全部兰州公交集团第一客运公司运营的
        公交线路。" href="/g21" title="兰州公交集团第一客运公司">兰州公交集团第一客运公司</a></li>, <li><span tabindex="0">最后更新:2022-06-24</span><div class="wechat-promote tooltip-btn" data--tooltip-align="center" data-tooltip-body="wechatPromote" wbfignoreele=""><i class="iconfont iconwechat"></i>免费发送线路信息到微信</div></li>, <li tabindex="0">※ 本查询结果仅供参考,车程及票价请以实际发生为准</li>]
        """
        # 从lis中获取想要的信息:
        # 1. 运行时间
        run_times = lis[0].text
        run_time_list.append(run_times)
        print(run_times)
        # 2. 参考票价
        tickets_price = lis[1].text
        ticket_price_list.append(tickets_price)
        print(tickets_price)
        # 3. 公交公司
        """
        <li><span tabindex="0">公交公司:</span><a aria-label="兰州公交集团第一客运公司,按回车键查看全部兰州公交集团第一客运公司运营的 公交线路。" href="/g21" title="兰州公交集团第一客运公司">兰州公交集团第一客运公司</a></li>,
        """
        bus_companies = lis[2].text
        bus_company_list.append(bus_companies)
        print(bus_companies)
        # 4. 最后更新时间
        last_updated = lis[3].text
        last_updated_list.append(last_updated)
        print(last_updated)
        print("-"*120)
        time.sleep(1)
        n += 1
        # 将最后的结果保存到字典中
        try:
            road_info_dic.update({"title": title_list, "run_time": run_time_list, "ticket_price": ticket_price_list,
                                  "bus_company": bus_company_list, "last_updated": last_updated_list})
            print("信息保持字典成成功~~~")
        except Exception as e:
            print("信息保持字典失败:"+e)
    print(f"获取信息成功,共获取 {n-1} 条信息")

    # print(road_info_dic)
    print("-"*120)
    info_df = pd.DataFrame(road_info_dic)
    print(f"{n1} 字头公交车所有线路信息为:")
    print(info_df)
    # 保存为csv文件(不同数字开头的公交车存为不同的文件,就是输入的数字)
    try:
        print("信息开始存入csv文件")
        progress()
        info_df.to_csv(os.path.join(os.getcwd(), 'files/') +
                       f"bus{n1}_info.csv", index=False, encoding='gbk')
        path = os.path.join(os.getcwd(), 'files')
        print("\n")
        print(f"保存csv文件成功,请在{path}文件夹下查看")
    except Exception as e:
        print("保存csv文件失败"+e)


get_every_raod_bus_info()

有关抓取每路公交的具体信息的更多相关文章

  1. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  4. ruby - 我需要从 facebook 游戏中抓取数据——使用 ruby - 2

    修改(澄清问题)我已经花了几天时间试图弄清楚如何从Facebook游戏中抓取特定信息;但是,我遇到了一堵又一堵砖墙。据我所知,主要问题如下。我可以使用Chrome的检查元素工具手动查找我需要的html-它似乎位于iframe中。但是,当我尝试抓取该iframe时,它​​是空的(属性除外):如果我使用浏览器的“查看页面源代码”工具,这与我看到的输出相同。我不明白为什么我看不到iframe中的数据。答案不是它是由AJAX之后添加的。(我知道这既是因为“查看页面源代码”可以读取Ajax添加的数据,也是因为我有b/c我一直等到我可以看到数据页面之后才抓取它,但它仍然不存在)。发生这种情况是因为

  5. ruby - what is - gets is a directory - 错误信息 - 2

    我遇到了这个奇怪的错误.../Users/gideon/Documents/ca_ruby/rubytactoe/lib/player.rb:13:in`gets':Isadirectory-spec(Errno::EISDIR)player_spec.rb:require_relative'../spec_helper'#theuniverseisvastandinfinite...itcontainsagame....butnoplayersdescribe"tictactoegame"docontext"theplayerclass"doit"musthaveahumanplay

  6. RUBY - 网页抓取 - (OpenURI::HTTPError) - 2

    我正在尝试用ruby​​编写一个简单的网络抓取代码。它一直工作到第29个url,然后我收到此错误消息:C:/Ruby193/lib/ruby/1.9.1/open-uri.rb:346:in`open_http':500InternalServerError(OpenURI::HTTPError)fromC:/Ruby193/lib/ruby/1.9.1/open-uri.rb:775:in`buffer_open'fromC:/Ruby193/lib/ruby/1.9.1/open-uri.rb:203:in`blockinopen_loop'fromC:/Ruby193/lib/r

  7. ruby - 尝试比较两个文本文件,并根据信息创建第三个 - 2

    我有两个文本文件,master.txt和926.txt。如果926.txt中有一行不在master.txt中,我想写入一个新文件notinbook.txt。我写了我能想到的最好的东西,但考虑到我是一个糟糕的/新手程序员,它失败了。这是我的东西g=File.new("notinbook.txt","w")File.open("926.txt","r")do|f|while(line=f.gets)x=line.chompifFile.open("master.txt","w")do|h|endwhile(line=h.gets)ifline.chomp!=xputslineendende

  8. ruby - rspec: raise_error 用法来匹配错误信息 - 2

    我使用raise(ConfigurationError.new(msg))引发错误我试着用rspec测试一下:expect{Base.configuration.username}.toraise_error(ConfigurationError,message)但这行不通。我该如何测试呢?目标是匹配message。 最佳答案 您可以使用正则表达式匹配错误消息:it{expect{Foo.bar}.toraise_error(NoMethodError,/private/)}这将检查NoMethodError是否由privateme

  9. ruby - 为什么要使用嵌套的 Ruby 模块来获取版本信息? - 2

    我最近一直在查看一些gem的源代码。我经常看到的一个习惯用法是使用嵌套模块,其中包含连接到版本字符串中的版本常量,即围绕此类事物的变体:moduleChunkyBaconmoduleVersionMAJOR=0MINOR=6TINY=2endVERSION=[Version::MAJOR,Version::MINOR,Version::TINY].compact*'.'end以这种方式存储库版本信息有什么好处(如果有的话)?为什么不这样做:moduleChunkyBaconVERSION='0.6.2'.freezeend 最佳答案

  10. ruby - 使用包含在另外两个数组中的信息创建一个数组 - 2

    如何使用如下两个数组构建一个数组:名称=[a,b,c]how_many_of_each[3,5,2]得到my_array=[a,a,a,b,b,b,b,b,c,c] 最佳答案 使用zip、flat_map和数组乘法:irb(main):001:0>value=[:a,:b,:c]=>[:a,:b,:c]irb(main):002:0>times=[3,5,2]=>[3,5,2]irb(main):003:0>value.zip(times).flat_map{|v,t|[v]*t}=>[:a,:a,:a,:b,:b,:b,:b,:b

随机推荐