背景:端午节假期的时候参加了学校的数学建模比赛,题目是关于共享单车的供需匹配问题,需要获得共享单车的数量和时空分布情况。

在苦苦找寻数据无果的情况下决定自己用爬虫对天津地区的mobike进行统计。

在网上找到了这篇爬虫的代码,本着少造轮子的基本原则,我选择了这个代码进行统计,这里记录一下历程,方便日后查阅。

先上原作者github地址:git clone https://github.com/derekhe/mobike-crawler。python3环境,爬取的是微信小程序,之前是可以爬手机客户端的,不过随着客户端完善变得难爬,小程序的爬取

能用到什么时候要也不确定。

我会把我的一些代码和数据放到百度云里,链接在文末,有需要的小伙伴可以自取。

一、数据之初探

首先确定了要爬取微信小程序的时候,先需要确定一个大概的方向,下载fiddler,对微信小程序进行抓包处理,这一步进展比较顺利。不太了解这一步的可以搜索手机APP抓包相关的知识,这里不再赘述。

比较容易的发现在请求页面需要post你的经纬度坐标给https://mwx.mobike.com/mobike-api/rent/nearbyBikesInfo.do这个网页,然后返回周围的车的信息,包括

bikeID,distX,distY,distance等信息,比较方便的是这些信息都放在了json文件中。而我们关系的只是车的位置和距离即distX,distY,distance。

注意点是要把浏览器头部伪装成手机浏览器。

z.json()['object']即可。

import requests

headers={'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Mobile/14E304 MicroMessenger/6.5.7 NetType/WIFI Language/zh_CN','Content-Type': 'application/x-www-form-urlencoded','Referer': 'https://servicewechat.com/wx80f809371ae33eda/23/page-frame.html',

}

url= 'https://mwx.mobike.com/mobike-api/rent/nearbyBikesInfo.do'data={'longitude':'121.1883',# 经度'latitude':'31.05147', # 纬度'citycode':'021','errMsg':'getMapCenterLocation:ok'}z= requests.post(url,data=data,headers=headers,verify=False)

二、数据之再思考

有了第一步的初探,下一步需要做的东西也十分清楚。要获得天津地区的Mobike数量可以近似画一个长方形,用爬虫爬取这个长方形内的自行车数目即可。

直接贴原作者的代码,我的代码在其中做了一些修改,不过我是放在了jupyter notebook中运行的,页面中有将近十万的运行结果数据的原因,每次打开代码都会卡死。。。

需要注意的点是,在我电脑上运行时找不到retrying库,直接去掉即可运行。运行结果放在db文件夹下。

offset设置为0.002左右即可,太大容易导致漏数,太小会有重复误差。这也是网上有其他代码用数据库的原因,不过由于数学建模的时间紧张,再加我对数据库不太熟悉,直接暴力设定爬取步长也没出现问题。

import datetime

import os

import os.path

import random

import sqlite3

import threading

import time

import ujsonfromconcurrent.futures import ThreadPoolExecutor

import numpyasnp

import requestsfromretrying import retryfrommodules.ProxyProvider import ProxyProviderclassCrawler:

def __init__(self):

self.start_time=datetime.datetime.now()

self.csv_path= "./db/" + datetime.datetime.now().strftime("%Y%m%d")

os.makedirs(self.csv_path, exist_ok=True)

self.csv_name= self.csv_path + "/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S") + '.csv'self.db_name= "./temp.db"self.lock =threading.Lock()

self.proxyProvider=ProxyProvider()

self.total= 0self.done= 0def get_nearby_bikes(self, args):try:

url= "https://mwx.mobike.com/mobike-api/rent/nearbyBikesInfo.do"payload= "latitude=%s&longitude=%s&errMsg=getMapCenterLocation" % (args[0], args[1])

headers={'charset': "utf-8",'platform': "4","referer":"https://servicewechat.com/wx40f112341ae33edb/1/",'content-type': "application/x-www-form-urlencoded",'user-agent': "MicroMessenger/6.5.4.1000 NetType/WIFI Language/zh_CN",'host': "mwx.mobike.com",'connection': "Keep-Alive",'accept-encoding': "gzip",'cache-control': "no-cache"}

self.request(headers, payload, args, url)

except Exceptionasex:

print(ex)

def request(self, headers, payload, args, url):whileTrue:

proxy=self.proxyProvider.pick()try:

response=requests.request("POST", url, data=payload, headers=headers,

proxies={"https": proxy.url},

timeout=5,verify=False

)

with self.lock:

with sqlite3.connect(self.db_name)asc:try:

print(response.text)

decoded= ujson.decode(response.text)['object']

self.done+= 1

for x indecoded:

c.execute("INSERT INTO mobike VALUES (%d,'%s',%d,%d,%s,%s,%f,%f)" %(int(time.time()) * 1000, x['bikeIds'], int(x['biketype']), int(x['distId']),

x['distNum'], x['type'], x['distX'],

x['distY']))

timespend= datetime.datetime.now() -self.start_time

percent= self.done /self.total

total= timespend /percent

print(args, self.done, percent* 100, self.done / timespend.total_seconds() * 60, total,

total-timespend)

except Exceptionasex:

print(ex)breakexcept Exceptionasex:

proxy.fatal_error()

def start(self):

left= 30.7828453209top= 103.9213455517right= 30.4781772402bottom= 104.2178123382offset= 0.002

ifos.path.isfile(self.db_name):

os.remove(self.db_name)try:

with sqlite3.connect(self.db_name)asc:

c.execute('''CREATE TABLE mobike

(Time DATETIME, bikeIds VARCHAR(12), bikeType TINYINT,distId INTEGER,distNum TINYINT, type TINYINT, x DOUBLE, y DOUBLE)''')

except Exception asex:

pass

executor= ThreadPoolExecutor(max_workers=250)

print("Start")

self.total= 0lat_range= np.arange(left, right, -offset)for lat inlat_range:

lon_range=np.arange(top, bottom, offset)for lon inlon_range:

self.total+= 1executor.submit(self.get_nearby_bikes, (lat, lon))

executor.shutdown()

self.group_data()

def group_data(self):

print("Creating group data")

conn=sqlite3.connect(self.db_name)

cursor=conn.cursor()

f= open(self.csv_name, "w")for row in cursor.execute('''SELECT * FROM mobike'''):

timestamp, bikeIds, bikeType, distId, distNumber, type, lon, lat=row

f.write("%s,%s,%s,%s,%s,%s,%s,%s\n" %(

datetime.datetime.fromtimestamp(int(timestamp) / 1000).isoformat(), bikeIds, bikeType, distId, distNumber, type, lon, lat))

f.flush()

f.close()

os.system("gzip -9" +self.csv_name)

Crawler().start()

三、数据简单处理和分析

爬取天津主城区(红桥区,河西区,河东区,和平区,南开区,河北区)和周边范围的Mobike,

爬取结果大概为98398辆,利用Kmeans聚类进行聚类分析。

分别取聚类点50,75,100,150,200来通过matplotlib绘图观察聚类结果。选择n_clusters=50。

得到聚类中心点坐标,然后再利用反解析软件解析坐标对应的地点信息,即可获得共享单车的主要分布区域。

最后,一些数据和代码放在百度云上,用则自取。

百度云地址:http://pan.baidu.com/s/1eRHjmVK密码:d5dw

以上。

:)

(2019.03.21更新:由于去年一整年都在备战考研,很多消息没来得及回。不幸的是我去年的时候那台老惠普死掉了,数据集也丢在了里边,所以目前我手上也没有数据集了,抱歉。)

python客户端开发自行车租赁系统_爬虫获取mobike共享单车信息相关推荐

  1. python客户端开发自行车租赁系统_python可视化--共享单车项目

    共享单车项目项目说明 自行车共享系统是一种租赁自行车的方法,注册会员.租车.还车都将通过城市中的站点网络自动完成, 通过这个系统人们可以根据需要从一个地方租赁一辆自行车然后骑到自己的目的地归还. 在这 ...

  2. python客户端开发自行车租赁系统_Python实战—自行车租赁数据分析

    本节选取自行车的租赁数据,利用numpy.pandas.matplotlib三个库,数据清洗后,做数据分析,研究时间段与自行车租赁的关系. 数据来源 本节以自行车的租赁数据为例,数据来源于网络,利用时 ...

  3. python客户端开发自行车租赁系统_Python数据分析,自行车租赁数据分析,租赁情况怎么样?...

    本节选取自行车的租赁数据,利用numpy.pandas.matplotlib三个库,数据清洗后,做数据分析,研究时间段与自行车租赁的关系. 数据来源 本节以自行车的租赁数据为例,数据来源于网络,利用时 ...

  4. python爬取pubmed的文献_爬虫获取pubmed中文献的标题和摘要

    为了满足快速浏览pubmed中相关文献标题和摘要的需求,写了个简单的爬虫(目前只实现了单个关键词以及多个关键词的and检索),用于批量获取感兴趣文献的标题和摘要. 使用编辑器是python,所编写的爬 ...

  5. 【压箱底】一种基于物联网的公共自行车租赁系统

    [整理收藏夹,线下的东西搬到线上,借下贵宝地] 一种基于物联网的公共自行车租赁系统  CN 105354935 A 摘要 本发明公开了一种基于物联网的公共自行车租赁系统的实现方法,用于解决传统基于固定 ...

  6. 计算机毕业设计JAVA校园自行车租赁系统mybatis+源码+调试部署+系统+数据库+lw

    计算机毕业设计JAVA校园自行车租赁系统mybatis+源码+调试部署+系统+数据库+lw 计算机毕业设计JAVA校园自行车租赁系统mybatis+源码+调试部署+系统+数据库+lw 本源码技术栈: ...

  7. 基于SpringBoot的自行车租赁系统的设计与实现

    摘 要 随着国家经济飞速发展和居民生活水平的提高,给城镇交通问题带来了巨大隐患.传统共享自行车系统的产生成为了解决交通问题的手段之一,城镇居民很难简单.方便的使用传统的共享自行车系统,所以如何让城镇居 ...

  8. javaweb校园自行车租赁系统

    校园自行车租赁系统主要是采用jsp的mvc技术.mysql数据库.Tomcat服务器作为开发平台,系统采用B/S结构进行开发.目标是实现一个以租赁为中心的校园自行车租赁系统,构建用户信息与账号,账号与 ...

  9. 基于java+springboot+mybatis+vue+elementui的校园自行车租赁系统

    项目介绍 许多先进国家早已致力于发展自行车替代高能耗.高排放的交通工具.然而传统落后的自行车租赁管理模式仍然在很大程度上制约了推行公共自行车租赁普及化和现代化的发展,成为更深层次的"软环境& ...

最新文章

  1. 你敢参与,我就敢送!牛转好运来,新春大抽奖
  2. 分享mac磁盘清理的方法
  3. 河北师范大学C语言试题,2017年河北师范大学信息技术学院838C语言程序设计考研题库...
  4. 【javascript位置属性】screen对象
  5. Hibernate sqlserver 的对象转成 Hibernate mysql 的对象时 需注意
  6. wepack环境配置1之node的安装
  7. 557. 反转字符串中的单词 III golang 数组和字符串反转
  8. 浦发银行出现:部件'InstallCertListAx.ocx'或其附件之一不能正确注册:一个文件丢失 解决...
  9. 从某软件引发的深思总结
  10. 单按钮启停电路实物图_什么是电路的主回路?什么是控制回路?它们之间有什么区别?...
  11. python写文件格式转换程序_有趣的python小程序——图片格式转换
  12. Gramine(原graphene-sgx)软件栈
  13. JAVA我的世界怎么做成就_我的世界:又一人解锁100%成就!这几项公认最难任务,你能完成吗...
  14. 中国药科大学校长来茂德:我眼中“医疗+AI”的机会与挑战
  15. pinctrl学习笔记---描述/获得引脚
  16. 你真的了解TCP/IP吗
  17. 通过css让图片设置成黑白色
  18. 删除桌面上文件,提示此文件位置不在当前位置?
  19. Entrust Datacard宣布与IBM Security开展目标远大的合作,以助力确保移动工作人员安全
  20. 史上最全开启windows7(win7)虚拟wifi教程(上)

热门文章

  1. Vijos P1404 遭遇战
  2. java经典代码片段
  3. iuni-summary
  4. App上线-Invalid AppStoreIcon-90717
  5. i7 10700和i5 10400F参数对比差距大吗
  6. Oracle创建自增主键ID(序列+触发器)
  7. 数据结构 - 串的模式匹配
  8. 监控swagger 接口变动
  9. 怎么写标题更加吸引人(几种吸引人的标题类型写法)
  10. Linux之在CentOS上一次艰难的木马查杀过程