开发背景
自己开发一款北京实时公交的小程序,奈何在网上苦苦寻找api接口无果,最后只得爬取网上数据
项目构思
1 选定爬虫框架—QueryList
2 数据源选定—北京公交网
3 根据需求将div格式化成json数据
开发实践
1 QueryList安装,利用composer直接进行安装,点我进官网查看示例

composer require jaeger/querylist

在控制器中引用

<?php
namespace app\index\controller;
use QL\QueryList;
class Index
{public function index(){//采集某页面所有的图片$data = QueryList::get('http://cms.querylist.cc/bizhi/453.html')->find('img')->attrs('src');//打印结果print_r($data->all());}
}

2 数据源接口确定

获取行驶方向

http://www.bjbus.com/home/ajax_rtbus_data.php?act=getLineDir&selBLine=428

返回内容

<a href="javascript:;" data-uuid="4907320871547002333">428(天通北苑-地铁龙泽站)</a>
<a href="javascript:;" data-uuid="5415569149649522461">428(地铁龙泽站-天通北苑)</a>

获取行驶情况

http://www.bjbus.com/home/ajax_rtbus_data.php?act=busTime&selBLine=1&selBDir=

返回内容

{"html": "<div class=\"inquiry_header\"><div class=\"left fixed\"><h3 id=\"lh\">428路</h3></div><div class=\"inner\"><h2 id=\"lm\">天通北苑-地铁龙泽站</h2><article><p>天通北苑&nbsp;5:30-23:00&nbsp;分段计价&nbsp;所属客一分公司</p><p>车辆均已过站</p></article></div></div><div id=\"cc_stop\" class=\"inquiry_main\" unselectable=\"on\" onselectstart=\"return false;\"><ul class=\"fixed\"><li><div id=\"1\"><i></i><p class=\"sicon\"></p><span title=\"天通北苑\">天通北苑</span></div></li><li><div id=\"2m\"><i ></i></div></li><li><div id=\"2\"><i></i><p class=\"sicon\"></p><span title=\"天通东苑三区西门\">天通东苑三区<br/>...</span></div></li><li><div id=\"3m\"><i ></i></div></li><li><div id=\"3\"><i></i><p class=\"sicon\"></p><span title=\"天通北苑三区南门\">天通北苑三区<br/>...</span></div></li><li><div id=\"4m\"><i ></i></div></li><li><div id=\"4\"><i></i><p class=\"sicon\"></p><span title=\"天通北苑三区南\">天通北苑三区<br/>...</span></div></li><li><div id=\"5m\"><i ></i></div></li><li><div id=\"5\"><i></i><p class=\"sicon\"></p><span title=\"天通北苑二区东门\">天通北苑二区<br/>...</span></div></li><li><div id=\"6m\"><i ></i></div></li><li><div id=\"6\"><i></i><p class=\"sicon\"></p><span title=\"狮子营西门\">狮子营西门</span></div></li><li><div id=\"7m\"><i ></i></div></li><li><div id=\"7\"><i></i><p class=\"sicon\"></p><span title=\"天通北苑二区北门\">天通北苑二区<br/>...</span></div></li><li><div id=\"8m\"><i ></i></div></li><li><div id=\"8\"><i></i><p class=\"sicon\"></p><span title=\"天通北苑一区北门\">天通北苑一区<br/>...</span></div></li><li><div id=\"9m\"><i  class=\"busc\" clstag=\"\"></i></div></li><li><div id=\"9\"><i></i><p class=\"sicon\"></p><span title=\"地铁天通苑北站南\">地铁天通苑北<br/>...</span></div></li><li><div id=\"10m\"><i ></i></div></li><li><div id=\"10\"><i></i><p class=\"sicon\"></p><span title=\"东三旗\">东三旗</span></div></li><li><div id=\"11m\"><i ></i></div></li><li><div id=\"11\"><i></i><p class=\"sicon\"></p><span title=\"半截塔村东站\">半截塔村东站</span></div></li><li><div id=\"12m\"><i ></i></div></li><li><div id=\"12\"><i></i><p class=\"sicon\"></p><span title=\"半截塔村北站\">半截塔村北站</span></div></li><li><div id=\"13m\"><i ></i></div></li><li><div id=\"13\"><i></i><p class=\"sicon\"></p><span title=\"魏窑村\">魏窑村</span></div></li><li><div id=\"14m\"><i ></i></div></li><li><div id=\"14\"><i></i><p class=\"sicon\"></p><span title=\"绿野福苑\">绿野福苑</span></div></li><li><div id=\"15m\"><i ></i></div></li><li><div id=\"15\"><i></i><p class=\"sicon\"></p><span title=\"小辛庄东\">小辛庄东</span></div></li><li><div id=\"16m\"><i ></i></div></li><li><div id=\"16\"><i></i><p class=\"sicon\"></p><span title=\"小辛庄\">小辛庄</span></div></li><li><div id=\"17m\"><i ></i></div></li><li><div id=\"17\"><i></i><p class=\"sicon\"></p><span title=\"小辛庄西\">小辛庄西</span></div></li><li><div id=\"18m\"><i ></i></div></li><li><div id=\"18\"><i></i><p class=\"sicon\"></p><span title=\"龙锦苑东二区北门\">龙锦苑东二区<br/>...</span></div></li><li><div id=\"19m\"><i ></i></div></li><li><div id=\"19\"><i></i><p class=\"sicon\"></p><span title=\"上坡路口西\">上坡路口西</span></div></li><li><div id=\"20m\"><i ></i></div></li><li><div id=\"20\"><i></i><p class=\"sicon\"></p><span title=\"和谐家园一区北门\">和谐家园一区<br/>...</span></div></li><li><div id=\"21m\"><i ></i></div></li><li><div id=\"21\"><i></i><p class=\"sicon\"></p><span title=\"龙锦苑二区\">龙锦苑二区</span></div></li><li><div id=\"22m\"><i ></i></div></li><li><div id=\"22\"><i></i><p class=\"sicon\"></p><span title=\"田园风光雅苑\">田园风光雅苑</span></div></li><li><div id=\"23m\"><i ></i></div></li><li><div id=\"23\"><i class=\"buss\" clstag=\"-1\"></i><p class=\"sicon\"></p><span title=\"龙锦苑四区\">龙锦苑四区</span></div></li><li><div id=\"24m\"><i ></i></div></li><li><div id=\"24\"><i></i><p class=\"sicon\"></p><span title=\"马连店南口\">马连店南口</span></div></li><li><div id=\"25m\"><i ></i></div></li><li><div id=\"25\"><i></i><p class=\"sicon\"></p><span title=\"龙禧苑三区北门\">龙禧苑三区北<br/>...</span></div></li><li><div id=\"26m\"><i ></i></div></li><li><div id=\"26\"><i></i><p class=\"sicon\"></p><span title=\"龙禧苑三区路口西\">龙禧苑三区路<br/>...</span></div></li><li><div id=\"27m\"><i ></i></div></li><li><div id=\"27\"><i></i><p class=\"sicon\"></p><span title=\"回龙观公交场站\">回龙观公交场<br/>...</span></div></li><li><div id=\"28m\"><i ></i></div></li><li><div id=\"28\"><i></i><p class=\"sicon\"></p><span title=\"风雅园北\">风雅园北</span></div></li><li><div id=\"29m\"><i ></i></div></li><li><div id=\"29\"><i></i><p class=\"sicon\"></p><span title=\"三合庄园\">三合庄园</span></div></li><li><div id=\"30m\"><i ></i></div></li><li><div id=\"30\"><i></i><p class=\"sicon\"></p><span title=\"龙华园\">龙华园</span></div></li><li><div id=\"31m\"><i ></i></div></li><li><div id=\"31\"><i></i><p class=\"sicon\"></p><span title=\"龙华园南区\">龙华园南区</span></div></li><li><div id=\"32m\"><i ></i></div></li><li><div id=\"32\"><i></i><p class=\"sicon\"></p><span title=\"地铁龙泽站\">地铁龙泽站</span></div></li></ul></div><div class=\"inquiry_footer\"><section><div class=\"inner\"><span class=\"buss\">途中车辆</span><span class=\"busc\">到站车辆</span></div></section></div>","w": 1532,"seq": "1"
}

3 将div格式化成json
获取公交线路比较简单,只有两个a标签,我们只需获取其中的text以及uuid就可以,以下是代码

  public function getBusLine($busName){$rules = [// 公交车名称'name' => ['a', 'text'],// 公交车uuid'uuid' => ['a', 'data-uuid']];//采集某页面所有的图片$data = QueryList::get('http://www.bjbus.com/home/ajax_rtbus_data.php?act=getLineDir&selBLine=' . $busName)->rules($rules)->query()->getData();;//打印结果$result = $data->all();if (count($result) === 0) {throw new ParameterException(['msg' => '暂无公交信息']);}for ($i = 0; $i < count($result); $i++) {$array = explode('(', $result[$i]['name']);$result[$i]['name'] = $array[0];$result[$i]['busLine'] = substr($array[1], 0, strlen($array[1]) - 1);}return $result;}

获取公交行驶情况比较复杂,需要注意span标签与i标签的关系

  public function getBusInfo($uuid){$rules = [// 公交车名称'status' => ['div>i', 'class'],'name' => ['div>span', 'title'],'headInfo' => ['article>p', 'text']];$result = get('http://www.bjbus.com/home/ajax_rtbus_data.php?act=busTime&selBLine=1&selBDir=' . $uuid . '&selBStop=1');$result = json_decode($result, true);if (!array_key_exists('html', $result)) {throw new ParameterException(['msg' => '查询公交信息失败']);}$data = QueryList::html($result['html'])->rules($rules)->query()->getData();$busResult = $data->all();$result = ['time' => '','busInfo' => [],'busc' => 0];$result['time'] = $busResult[0]['headInfo'];//for循环是精髓for ($i = 0; $i < count($busResult) / 2; $i++) {$resultItem = [];$resultItem['busName'] = $busResult[$i]['name'];if ($i == 0) {$resultItem['buss'] = $busResult[$i]['status'] == 'buss';$resultItem['busc'] = $busResult[$i + 1]['status'] == 'busc';if ($resultItem['buss']) {$result['busc'] = $result['busc'] + 1;}if ($resultItem['busc']) {$result['busc'] = $result['busc'] + 1;}} else {$resultItem['buss'] = $busResult[($i * 2)]['status'] == 'buss';if ($resultItem['buss']) {$result['busc'] = $result['busc'] + 1;}if ($i !== (count($busResult) - 1) / 2) {$resultItem['busc'] = $busResult[($i * 2 + 1)]['status'] == 'busc';if ($resultItem['busc']) {$result['busc'] = $result['busc'] + 1;}}}array_push($result['busInfo'], $resultItem);}return $result;}

4 最后格式化完成后的json数据
公交线路

{"responseCode": 0,"responseMessage": "查询成功","data": [{"name": "428","uuid": "4907320871547002333","busLine": "天通北苑-地铁龙泽站"},{"name": "428","uuid": "5415569149649522461","busLine": "地铁龙泽站-天通北苑"}]
}

公交信息(其中busc表示途中车辆,buss表示到站车辆)

{"responseCode": 0,"responseMessage": "查询成功","data": {"time": "天通北苑 5:30-23:00 分段计价 所属客一分公司","busInfo": [{"busName": "天通北苑","buss": false,"busc": false},{"busName": "天通东苑三区西门","buss": false,"busc": false},{"busName": "天通北苑三区南门","buss": false,"busc": false},{"busName": "天通北苑三区南","buss": false,"busc": false},{"busName": "天通北苑二区东门","buss": false,"busc": false},{"busName": "狮子营西门","buss": false,"busc": false},{"busName": "天通北苑二区北门","buss": false,"busc": false},{"busName": "天通北苑一区北门","buss": false,"busc": false},{"busName": "地铁天通苑北站南","buss": false,"busc": false},{"busName": "东三旗","buss": false,"busc": false},{"busName": "半截塔村东站","buss": false,"busc": false},{"busName": "半截塔村北站","buss": false,"busc": false},{"busName": "魏窑村","buss": false,"busc": false},{"busName": "绿野福苑","buss": false,"busc": false},{"busName": "小辛庄东","buss": false,"busc": false},{"busName": "小辛庄","buss": false,"busc": false},{"busName": "小辛庄西","buss": false,"busc": false},{"busName": "龙锦苑东二区北门","buss": false,"busc": false},{"busName": "上坡路口西","buss": false,"busc": false},{"busName": "和谐家园一区北门","buss": false,"busc": false},{"busName": "龙锦苑二区","buss": false,"busc": false},{"busName": "田园风光雅苑","buss": false,"busc": false},{"busName": "龙锦苑四区","buss": false,"busc": false},{"busName": "马连店南口","buss": false,"busc": false},{"busName": "龙禧苑三区北门","buss": false,"busc": false},{"busName": "龙禧苑三区路口西","buss": false,"busc": false},{"busName": "回龙观公交场站","buss": false,"busc": false},{"busName": "风雅园北","buss": false,"busc": false},{"busName": "三合庄园","buss": false,"busc": false},{"busName": "龙华园","buss": false,"busc": true},{"busName": "龙华园南区","buss": false,"busc": false},{"busName": "地铁龙泽站","buss": false}],"busc": 1}
}

总的来说,比较简单,需要注意的就是两个接口关联的地方uuid,以及span与i标签的关系

开发那点事(六)php抓取北京实时公交数据相关推荐

  1. python抓取股市实时交易数据_python实时读取股票大单交易数据

    代码如下,有时可以读取成功,有时显示错误Exception:'gb2312' codec can't decode bytes in position 1-2, 不晓得原因是什么,跪求大神指点~ # ...

  2. Python爬虫实战六之抓取爱问知识人问题并保存至数据库

    大家好,本次为大家带来的是抓取爱问知识人的问题并将问题和答案保存到数据库的方法,涉及的内容包括: Urllib的用法及异常处理 Beautiful Soup的简单应用 MySQLdb的基础用法 正则表 ...

  3. 小猪的Python学习之旅 —— 20.抓取Gank.io所有数据存储到MySQL中

    小猪的Python学习之旅 -- 20.抓取Gank.io所有数据存储到MySQL中 标签:Python 一句话概括本文: 内容较多,建议先mark后看,讲解了一波MySQL安装,基本操作,语法速成, ...

  4. 通达信接口怎么样抓取股票实时数据?

    通达信接口怎么样抓取股票实时数据?股票爬取接口在股票交易中常常使用到的一些辅助工具,股票爬取接口主要是利用l1和l2接口来执行获取股票实时行情数据的原理,将自己需要查询的需求就可以在接口软件上搜索就可 ...

  5. Burpsuite 抓取微信小程序数据包

    Burpsuite 抓取微信小程序数据包 一.网上的方法 ① 手机导入CA证书,设置指定DNS,亲测无效 备注:此方法可抓取微信公众号的数据,但是无法抓取微信小程序的数据 ② 使用安卓模拟器,我下载的 ...

  6. python抓取内存中的网页_『爬虫四步走』手把手教你使用Python抓取并存储网页数据!...

    爬虫是Python的一个重要的应用,使用Python爬虫我们可以轻松的从互联网中抓取我们想要的数据,本文将基于爬取B站视频热搜榜单数据并存储为例,详细介绍Python爬虫的基本流程.如果你还在入门爬虫 ...

  7. 结束 txt进程_Python多进程抓取拉钩网十万数据

    转载:Python多进程抓取拉钩网十万数据 准备 安装Mongodb数据库 其实不是一定要使用MongoDB,大家完全可以使用MySQL或者Redis,全看大家喜好.这篇文章我们的例子是Mongodb ...

  8. 绕过SSL双向校验抓取Soul App的数据包

    参考了这篇文章:Android抓包总结 - 先知社区 https://xz.aliyun.com/t/6551#toc-10 毫无反编译经验的我,硬着头皮参考这篇文章抓到数据,记录一下抓包过程,全部是 ...

  9. 抓取微信运动真实数据

    wxSportCrawler,抓取微信运动真实数据的项目 链接:https://cnodejs.org/topic/57fc409a27a1d99178a98d3c

  10. python爬取京东图书_Python抓取京东图书评论数据

    Python抓取京东图书评论数据 来源:中文源码网    浏览: 次    日期:2018年9月2日 [下载文档:  Python抓取京东图书评论数据.txt ] (友情提示:右键点上行txt文档名- ...

最新文章

  1. 从源码分析DEARGUI之文件选择
  2. python语句结束标志_jinja2.exceptions.TemplateSyntaxError:预期标记“打印语句结束”,已“发布” - python...
  3. Extension field添加到CDS view上的技术实现
  4. mysql中怎么在列中使用时间函数_mysql中关于时间的函数使用教程
  5. Security中常见的权限控制方式
  6. 数据可视化设计的UI实用模板素材
  7. 蓝桥杯---特别数的和(C语言)
  8. 直接保存 DataFrame 表格到本地,这个“骚操作”你还不知道?
  9. android 通知写法_Android架构设计MVP模式第(二)篇,如何减少类爆炸
  10. 34.了解那些算法要求使用排序的区间作为参数
  11. vs编译之连接器工具警告LNK4099的解决
  12. 向博客园提交了MVP申请
  13. 缓存算法篇其一-----FIFO(先入先出)
  14. 浏览器的滚动条滚动时,导航条的背景变色
  15. 什么是企业邮箱?企业邮箱有什么用途?
  16. Android中的传感器之---光线传感器
  17. 苹果的名字测试软件,抖音手机称重是什么软件叫什么名字 怎么用iPhone苹果手机称重...
  18. java计算机毕业设计宠物店管理系统设计与实现(附源码、数据库)
  19. 2022年网络工程师考试知识点:广域网技术
  20. Geant4学习之CAD模型导入(2)

热门文章

  1. 深度Linux怎样关闭休眠,deepin如何休眠,
  2. Excel如何实现行列转换及行倒置
  3. TDengine 荣获 CSDN IT 技术影响力之星 “年度开源项目” 、 “年度IT领军人物”奖项
  4. 轻量级任务调度中间件
  5. JS放大镜小功能功能之原理详细解析
  6. 第四章——波形与矢量AWGN信道
  7. Meltdown(熔断漏洞)- Reading Kernel Memory from User Space/KASLR | 原文+中文翻译
  8. c语言用函数写大小写转换,C语言实现大小写转换的三种方法
  9. 2019个税计算公式(附最新个税计算器)
  10. 方法调用错误,例如: