爬取北京市公交线路信息

这篇文章主要讲述了爬取北京市公交线路信息的整个过程,对于小白还是极为友好的,细节解释的比较详细,话不多说,开始探索知识吧。
一、Xpath插件
1、文件夹格式插件安装
  1.首先用户点击谷歌浏览器右上角的自定义及控制按钮,在下拉框中选择设置。
  2.在打开的谷歌浏览器的扩展管理器最左侧选择扩展程序。
  3.勾选开发者模式,点击加载已解压的扩展程序,将文件夹选择即可安装插件。

2、使用方式
  (1)打开方式快捷键
   Ctrl+Shift+X,如果打不开,就重新加载一下
  (2)取元素的XPath
  按住Shift键,将鼠标移到需要定位的元素上,该元素会以黄色底纹高亮。左边的XPath编辑框内会显示该元素的XPath路径,右边的节点文本显示框会显示该元素的文本内容。
  (3)检验XPath路径
  在编辑框内输入自己事先写好的XPath路径,检查书写是否有误。
二、爬取第一页所有的导航链接
以爬取数字1开头的公交线路为例,一级网页:beijing.8684.cn/,二级网页:beijing.8684.cn/list1,就多了一个/list1,所以就要在一级网页中找到/list1,在一级网页基础上加上即可,其余以此类推。那么如何准确找到以1开头的公交线路的/list1呢,用xpath。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
代码解读为://div[@class=“bus-layer depth w120”]表示要获取class="bus-layer depth w120"下面的值,/div[1]表示获取class="bus-layer depth w120"下面第一个div的值,/div/a/@href表示获取div下a中herf的值,也就是/list1,可以找到lint1-9共9个结果,分别对应1-9开头的公交车。总之就是从上到下,层层递进,找到你唯一想找到的东东,可以通过/div[@]直接取值,也可以通过div[1]索引取值。

#爬取第一页所有的导航链接
def parse_navigation():
    url = 'https://beijing.8684.cn/'
    req = requests.get(url, headers=headers)
    #解析内容,获取所有的导航链接
    tree=etree.HTML(req.text)
    #查找以数字开头的所有链接
    number_herf_list=tree.xpath('//div[@class="bus-layer depth w120"]/div[1]/div/a/@href')
    #查找以字母开头的所有链接
    char_herf_list=tree.xpath('//div[@class="bus-layer depth w120"]/div[2]/div/a/@href')
    #将所有爬取到的链接返回
    return number_herf_list+char_herf_list
    # return number_herf_list

运行结果:
在这里插入图片描述
三、爬取二级页面,需要找到以1开头的所有路线的url
思路与上面一致,先看看该网页与上级网页网址有什么区别,一级网页:beijing.8684.cn/,三级页面:https://beijing.8684.cn/x_322e21c5,现在的目标就是爬取以1开头所有公交车的值,为请求三级页面打基础。
遍历上面的列表,依次发送请求,解析内容,获取每一个页面所有公交线路的url,先进入二级网页,再解析二级网页的内容。
二级页面:
在这里插入图片描述

def parse_erji(navi_list):
    # 遍历上面的列表,依次发送请求,解析内容,获取每一个页面所有公交线路的url
    for first_url in navi_list:
        first_url='https://beijing.8684.cn'+first_url
        print("开始爬取%s所有公交信息" % first_url)
        r=requests.get(first_url,headers=headers)
        #解析内容,获取每一路公交的详细url
        parse_erji_route(r.text)  #解析一下r的内容
        print("结束爬取%s所有公交信息" % first_url)

在这里插入图片描述
xpath的获取方式与一级页面一致,见上图。

def parse_erji_route(content):
    tree=etree.HTML(content)
    #写xpath,获取每一个线路
    route_list=tree.xpath('//div[@class="cc-content"]/div[2]/a/@href')
    route_name = tree.xpath('//div[@class="cc-content"]/div[2]/a/text()')
    i=0
    #遍历上面这个列表
    for route in route_list:
        print("开始爬取%s线路" % route_name[i])
        route='https://beijing.8684.cn'+route
        r=requests.get(route,headers=headers)
        # 解析内容,获取每一路公交的详细信息
        parse_sanji_route(r.text)
        print("结束爬取%s线路" % route_name[i])
        i+=1

四、进入三级页面,爬取需要的东东
第三步已经找到了进入三级页面的url了,这个适时候我们就应该享受胜利的果实了。立即推=进入三级页面,爬取我们需要的东东。话不多说,先看看三级页面的样子吧。
在这里插入图片描述
在这里插入图片描述
找到需要爬取内容的源码,这个xpath怎么写都行,只要能找到唯一对应的那个东东就中,比如我们需要线路运行时间,代码如下:

run_time=tree.xpath('//ul[@class="bus-desc"]/li[1]/text()')[0][5:]

在这里插入图片描述
//ul[@class=“bus-desc”]/li[1]是追踪到那个目录下,/text()是获取到里面内容:运行时间:老山公交场站5:00-23:00|四惠枢纽站5:00-23:00;tree.xpath(’//ul[@class=“bus-desc”]/li[1]/text()’)返回的是一个列表,[0][5:]是获取里面第一个值,第一个值中从第5个字符以后的内容,也就是:老山公交场站5:00-23:00|四惠枢纽站5:00-23:00。
代码:

def parse_sanji_route(content):
    tree=etree.HTML(content)
    #获取公交线路信息
    bus_num=tree.xpath('//h1[@class="title"]/text()')[0]
    #获取公交运行时间
    run_time=tree.xpath('//ul[@class="bus-desc"]/li[1]/text()')[0][5:]
    #获取票价信息
    ticket_info=tree.xpath('//ul[@class="bus-desc"]/li[2]/text()')[0][5:]
    #获取更新时间
    gxsj=tree.xpath('//ul[@class="bus-desc"]/li[4]/text()')[0][5:]
    # 获取起始站点
    start_finsh = tree.xpath('//div[@class="layout-left"]/div[@class="bus-excerpt mb15"][1]/div/div[2]/text()')[0]
    num=tree.xpath('//div[@class="bus-excerpt mb15"]')
    if len(num)==2:
        #获取上行总站数
        up_total=tree.xpath('//div[@class="bus-excerpt mb15"][1]/div[2]/div/text()')[0]
        #获取上行所有站名
        up_site_list=tree.xpath('//div[@class="layout-left"]/div[@class="bus-lzlist mb15"][1]/ol/li/a/text()')
        # 获取下行总站数
        down_total = tree.xpath('//div[@class="bus-excerpt mb15"][2]/div[2]/div/text()')[0]
        # 获取下行所有站名
        down_site_liet = tree.xpath('//div[@class="layout-left"]/div[@class="bus-lzlist mb15"][2]/ol/li/a/text()')

        #将每一条公交线路信息放到字典中
        item={
            "线路名":bus_num,
            "运行时间":  run_time,
            "票价信息":  ticket_info,
            "更新时间":  gxsj,
            "上行站数":  up_total,
            # "上行站点":  up_site_list,
            "下行站数":  down_total,
            # "下行站点":  down_site_liet,
            "起始站点":  start_finsh
        }
    else:
        # 获取环形所有站名
        circle_site_list = tree.xpath('//div[@class="layout-left"]/div[@class="bus-lzlist mb15"]/ol/li/a/text()')
        # 获取环形总站数
        circle_total = tree.xpath('//div[@class="bus-excerpt mb15"]/div[2]/div/text()')[0]
        item = {
            "线路名":bus_num,
            "运行时间":run_time,
            "票价信息":ticket_info,
            "更新时间":gxsj,
            "上行站数":circle_total,
            "下行站数": "无",
            "起始站点": start_finsh
            # "环形站点":circle_site_list,

        }

    items.append(item)

到此为止,我们所需要的东东就爬出来了,接下来,我们就要把它放到excle表格中去。
五、把内容导入excle
在这说明一下,这块一直没有找到特别固定的导入方式,因为偷懒用了个这,欢迎大家批评指正。

# 1.创建 Workbook
wb = xlwt.Workbook()
# 2.创建 worksheet
ws = wb.add_sheet('test_sheet')
# 3.写入第一行内容  ws.write(a, b, c)  a:行,b:列,c:内容
ws.write(0, 0, '线路名')
ws.write(0, 1, '运行时间')
ws.write(0, 2, '票价信息')
ws.write(0, 3, '更新时间')
ws.write(0, 4, '上行站数')
ws.write(0, 5, '下行站数')
ws.write(0, 6, '起始站点')
# 保存文件
wb.save('北京公交详细信息.xls')

def main():
    # with open('北京公交.txt', 'w', encoding='utf-8') as file:
    try:
        #爬取第一页所有的导航链接
        navi_list=parse_navigation()
        #爬取二级页面,需要找到以1开头的所有路线
        parse_erji(navi_list)
        # fp=open('郑州公交.text','w',encoding='utf8')
        #爬取完毕
        for i, item in enumerate(items):
            ws.write(i + 1, 0, item['线路名'])
            ws.write(i + 1, 1, item['运行时间'])
            ws.write(i + 1, 2, item['票价信息'])
            ws.write(i + 1, 3, item['更新时间'])
            ws.write(i + 1, 4, item['上行站数'])
            ws.write(i + 1, 5, item['下行站数'])
            ws.write(i + 1, 6, item['起始站点'])
        wb.save('北京公交详细信息.xls')

    except requests.exceptions.ConnectionError:
        print('Handle Exception')
    except AttributeError as e:
        print('Handle Exception')

六、总结
最后,再简单的总结一下爬取多级页面的思路,请求访问一级网址—解析网站的内容—在一级网页的源码中找到二级网页的入口—请求访问二级网址—解析网站的内容—在二级网页的源码中找到三级网页的入口—往复循环—直到找到你要爬取内容的地方进行收割你想要的东东。欢迎大家批评指正。

### 回答1: 可以使用Python中的urllib库来爬取北京公交线路信息。具体步骤如下: 1. 打开北京公交网站(http://www.bjbus.com/home/index.php)。 2. 在网站上找到“线路查询”功能,输入要查询的公交线路。 3. 在查询结果页面中,找到要的公交线路信息。 4. 使用urllib库中的urlopen()函数打开查询结果页面,获取页面内容。 5. 使用正则表达式或BeautifulSoup等工具,从页面内容中提取要的公交线路信息。 6. 将提取到的公交线路信息保存到本地或数据库中。 要注意的是,爬取网站信息要遵守相关法律法规,不得进行非法操作。同时,也要注意网站的反爬虫机制,避免被封禁IP等情况发生。 ### 回答2: 要使用urllib爬取北京公交线路信息要先了解一下相关的数据接口。目前,北京公交的数据接口已经开放,在网页上可以找到相应的API文档,其中包含了公交线路信息的获取方法。 在使用urllib进行爬取时,要先使用urlopen函数获取API网址的数据,然后使用json.loads函数将获取到的数据转换为json格式,便于对其进行处理。 在获取到json数据之后,要对其进行分析和筛选,以便获取到要的公交线路信息。具体来说,要从json数据中提取出线路名称、全程行驶时间、起点和终点等信息,并进行存储和处理。对于不同的数据格式和结构,要编写相应的代码进行处理和转换。 值得注意的是,由于公交线路信息的实时变化,要及时更新所获取的数据,以保证数据的准确性和完整性。另外,在进行数据爬取时,要遵守相关的法律法规,合理使用数据接口,确保数据安全和传输的合法性。 总的来说,使用urllib爬取北京公交线路信息要对公交数据接口的使用方式有一定的了解,要编写相应的代码进行数据处理和存储,并要遵守相关法律法规,保证数据的安全和合法性。 ### 回答3: 要使用urllib爬取北京公交线路信息要先了解一下公交线路信息的获取方式。北京市交通委员会的官网上提供了公交线路查询服务,通过这个服务可以查询到各个公交线路的详细信息,包括线路名称、起始点、终点、站点、运行时间票价等。 通过分析这个查询服务的URL,可以发现它是通过GET方式接收查询参数的,我们只要构造查询参数,然后将其拼接到查询URL后面,就可以获取到相应的查询结果了。 在Python中,可以使用urllib库来构造URL和发送HTTP请求,获取查询结果。具体步骤如下: 1. 构造查询URL 根据查询服务的URL构造查询URL,并设置查询参数,比如查询线路名称为“103”的公交信息: url = 'http://www.bjbus.com/home/ajax_search.php' params = { 'act': 'getLineDir', 'selBLine': '103' } url += '?' + urllib.parse.urlencode(params) 2. 发送HTTP请求 使用urllib库的urlopen()方法发送HTTP请求,并读取响应数据: response = urllib.request.urlopen(url) data = response.read().decode('utf-8') 3. 解析响应结果 查询服务返回的结果是一个JSON格式的字符串,可以使用Python提供的JSON解析库解析出结果: import json result = json.loads(data) print(result) 解析出来的结果是一个嵌套的字典和列表结构,包含了公交线路的详细信息要注意的是,由于查询服务是通过AJAX异步请求来实现的,所以要设置一些HTTP请求头参数才能成功获取查询结果,比如: headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3', 'Referer': 'http://www.bjbus.com/home/index.php' } request = urllib.request.Request(url, headers=headers) 另外,北京公交线路比较多,直接爬取所有线路信息可能会导致数据量过大,建议使用多线程或异步IO等技术来优化爬虫效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值