0


AIS数据爬虫---以船讯网为例

[01] 船舶自动识别系统(Automatic Identification Systems, AIS)是一种应用于船和岸、船和船之间的海事安全与通信的助航系统,在减少船舶碰撞事故等海事服务中发挥重要作用。随着AIS系统的应用和推广,越来越多研究者采用AIS数据船舶状态和航行轨迹,了解船舶航行环境中潜在的航行风险因素,为开展船舶航行安全特别是船舶会遇领域研究提供基础性条件;

[02] 2000年12月,国际海事组织航行分委会正式发布关于船舶必须强制安装AIS设备的提案,其明确要求2002年以后建造的船舶和从2008年开始运营的船舶都必须安装AIS系统;

[03] 自此AIS数据呈现指数性增长,无论是海事部门还是民用的航运数据中心都已积累了海量AIS历史记录。AIS积累了大量船舶航行和航运业信息,是一种宝贵的航运大数据资源;

[04] AIS数据在港口运营管理、船舶运营管理、船队动态监控、海事管理、船舶避碰量化研究等多方面具有重要意义。需要根据现有船舶航行的实际数据,即AIS数据,分析船舶典型多船会遇情景中影响因素,发挥船舶驾驶辅助决策的功能;

[05] AIS数据对于从事水上交通科研人员来说是具有重大意义的一份数据,如何得到具有正确性、连续性的AIS数据呢;

[06] 首先,海事机构单位是拥有大量的、丰富的的AIS源码数据(例:!AIVDM,1,1,,B,177KQJ5000G?tO`K>RA1wUbN0TKH,0*5C),也拥有已经解析好的AIS数据;

[07] 其次,各从事航海服务的信息公司,如船讯网、HiFleet等,我们可以从他们手中购买各种海事数据;

[08] 再者,各公开信息网站,如:“中国海洋卫星数据网站https://osdds.nsoas.org.cn/#/”、“美国国家海洋和大气管理局NOAA Office for Coastal Management”等,但是有些下载不了,有些下载很慢,且数据量庞大;

[09] 最后,就是本文提出的数据爬虫,预先获取好我们需求爬取船舶的mmsi就可驱动程序去获取想要的AIS数据;

[10] 本文以船讯网为例---'https://www.shipxy.com/'。登录好我们的船讯网账号后,在主页面按F12打开网页代码界面,再刷新一下,在船讯网主页面随机选中一首船舶,可以在网页代码界面---网页---Fetch/XHR---名称,找到GetShip可以看到对应网页代码“headers”---常规,由图1我们可以得到爬虫的请求URL(写代码需要用到)和请求方式(post);找到GetShip可以看到对应网页代码“headers”---请求标头,由图2可以看到一个代码方式User-Agent(写代码需要用到);


图1


图2

[11] 再点击预览,由图3我们可以查看选中船舶的AIS数据,具体数据解释意思如表1;由图3和表1可以观察到数据类型为int和str,但是AIS数据的经纬度、航速、航向、船长、船宽等数据可以观察到是明显对应不上的,因为某些存在保留几位小数点的,(如:cog=1868010e-2=186.80°、draught=1160010e-3=11.60m、hdg=1870010e-2=187°、lat=3814064510e-6=38.140645°、lon=121907823*10e-6=121.907823°,laststa=1687791619=’2023-06-26 23:00:19’,…);


图3

表1
index数据类别中文意思实例解释1mmsi水上移动通信业务标识码414223000***2imo国际海事组织识别码0= Not available**3callsign船舶呼号BRPM*4name船舶名称YU DE*5cnname船舶中文名称育德*6shipid船舶ID0EA73979DF6AA310*7length船长(dm)2000200m8width*船宽(dm)32032m*9left左舷距(dm)80*10draught*吃水(mm)1160011.6m*11trail尾距(dm)410*12source0*13type船舶类型70Cargo14tradetype交易类型(内贸\外贸)1*15matchtype1*16lon*经度(*1e-6°)119665810119.665810°*17*lat*纬度(1e-6°)3992974739.929747°*18sog对地航速(mm/s)00kn19cog*航迹向(1e-2°)30390303.9°*20hdg船首向(1e-2°)460046.0°21rot转向率(1e-2°/s)0*22navistatus航行状态5Moored23laststa开始时间(unix时间戳)16877862162023/6/26 21:3024lastdyn结束时间(unix时间戳)16877864192023/6/26 21:3325satelliteutc卫星世界时间(unix时间戳)0*26eta预计到达时间****2023/7/3 16:00\ 27dest目的地QINZHOU,CN中国, 钦州
[12] 现在我们有了爬取的数据源的各类信息,我们需要借助的工具为MySQL数据库软件和python编程软件(本文是基于pycharm);

[13] 首先我们下载好MySQL数据库---‘https://dev.mysql.com/downloads/’,安装好配置好环境变量,设置好一个账号‘root’和密码‘********’,打开安装好的‘MySQL workbench’导入我们需要爬取船舶的MMSI数据表数据表(如:文件mmsi.csv)需求格式为表2;

表2
indexmmsi14142230002636010329n-1286697660n****533009000
[14] 设置好我们需要保存爬取的AIS数据表(如:trail_cf),设置好保存数据的列名(如: mmsi,imo,name,callsign,dest,eta,length,width,draught,lon,lat,sog,cog,hdg,rot,navistatus,laststa,lastdyn,satelliteutc,…)数据库中的数据类型全部设置为str(即, VARCHAR(45));

[15] 打开pycharm,先下载一个‘Database navigator’插件,下载好重启IDE,打开视图---工具窗口---DB browser。按照图4所示内容(其他内容和图中一样,输入我们设置的密码即可),选择‘Test Connection’测试一下是否连接数据库成功,再确定;


图4

[16] 此时开始写代码,调用库;

import os
import pymysql
import requests

[17] 连接数据库;

self.conn = pymysql.connect(host="127.0.0.1", port=3306, user="root", password="********", database="cf",charset="utf8")
# 连接MySQL数据库,用户主机名或ip,默认是3306,用户名,密码,数据库,编码方式
self.cursor = self.conn.cursor() # 数据库连接操作<pymysql.cursors.Cursor object at 0x000001CB2F511DC0>
self.last_path = os.path.abspath(os.path.dirname(os.getcwd())) # 获得你刚才所引用的模块所在的绝对路径

[18] 获取数据库中预先导入的船舶MMSI数据表;

mmsi_sql = "select distinct mmsi from cf_test order by mmsi"
self.cursor.execute(mmsi_sql)
mmsi_group = self.cursor.fetchall()

[19] 从船讯网爬取AIS数据;

self.ship = ship
headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.58'                 
}
session = requests.Session()
main_url = 'https://www.shipxy.com/'  # 推测对该url发起请求会产生cookie
session.post(main_url, headers=headers)
url = 'https://www.shipxy.com/ship/GetShip'
dic2 = {
     'mmsi': ship
}
rq2 = session.post(url, headers=headers, params=dic2).json()

[20] 将数据爬取并保存在列表中;

mmsi_group = self.get_mmsi()
data = []
j = 0
for i in mmsi_group:
    ship = i[0]
    print(ship)
    result2 = self.get_rq2(ship)  # json.loads(rq2.text)是将都到的json数据转成json
    print(result2)
    while int(result2['status']) != 0:   # 在数据爬取的时候可能存在数据爬取错误,爬不到的情况,当status ==0 时数据爬取成功!
        result2 = self.get_rq2(ship)     # 构建一个while语句直到爬取成功时,再执行爬取下一条数据
        print(result2)
        data.append(result2['data'][0])
     j = j + 1
     if divmod(j, 100)[1] == 0:
          print("已经请求" + str(j) + "条")
print("已完成查询,准备入库....")
self.in_database(data)

[21] 从列表中提取所需要的数据存入MySQL数据库中;

 def in_database(self, data_list):         # data_list为所有数据的列表
        j = 1
        for i in data_list:
            insert_sql = '''insert into cf_ais(`mmsi`,`imo`,`callsign`,`name`,`cnname`,`shipid`,`length`,`width`,`left`,
            `draught`,`trail`,`source`,`type`,`tradetype`,`matchtype`,`lon`,`lat`,`sog`,`cog`,`hdg`,`rot`,`navistatus`,
            `laststa`,`lastdyn`,`satelliteutc`,`eta`,`dest`) values("{}","{}","{}","{}","{}","{}","{}","{}","{}","{}",
            "{}","{}","{}","{}","{}","{}","{}","{}","{}","{}","{}","{}","{}","{}","{}","{}","{}")'''.format(
                i['mmsi'], i['imo'], i['callsign'], i['name'], i['cnname'], i['shipid'], i['length'], i['width'],
                i['left'], i['draught'], i['trail'], i['source'], i['type'], i['tradetype'], i['matchtype'], i['lon'],
                i['lat'], i['sog'], i['cog'], i['hdg'], i['rot'], i['navistatus'], i['laststa'], i['lastdyn'],
                i['satelliteutc'], i['eta'], i['dest'])
            print(insert_sql)
            self.cursor.execute(insert_sql)
            print("已经插入第" + str(j) + "条,mmsi = " + i['mmsi'])
            self.conn.commit()
            j = j+1

[22] 爬取数据展示表3;

表3
mmsiimocallsignnamecnnameshipidlengthwidthleftdraughttrailsourcetypetradetypematchtypelonlatsogcoghdgrotnavistatuslaststalastdynsatelliteutcetadestcountry2054210009230050ONCEEXCALIBUR297A12C3B03A3AD32770430280750055008920552710022525375303600051100051687686506168786497502023/5/15 10:30PORT RASHIDAE"2057030009750024ONITGREEN ZEEBRUGGE4F755F0F7E9DACD110801801044003000842047725655242184303454034100051687782376168786498402023/6/26 18:00AMSTERDAMNL"20927500098198825BZQ4KAIROS4E80860467E22093117020012058001060080204772648524226420535034200051687720609168786488302023/6/24 20:00AMSTERDAMNL"20935100097685265BBL5NIKOLAY ZUBOVE339E87CC60D741A299050031010600790089203427666271978592833495609400-301685619948168723113916878641562023/4/18 19:00FOR ORDERS20935600097683945BBK5BORIS DAVYDOV69EA4E9F7E391C9529905003101100079008420-332670349671812895159105700201687796282168786512802023/7/3 19:01FOR ORDERS2094070009332054C4YF2GRAND ELENAC16078B43919CA72288049033011200660084201.37E+084166500061222146021200001687727013168782501416878646832023/7/1 23:30TIANJINCN"20985600093389295BCP2GRAND MEREYA61CFCEDE86A8732628904902709600670081201.28E+083155492384881837018500-201687820110168786413302023/6/30 23:00SHEKOUCN"20999700098771455BNK5GAIL BHUWAND1F293E99D6BE69429804802501120065008120348462432651835592091422013600101687700564168786199716878648172023/7/4 18:31MAGDALLAIN"21261100097371875BNR4CHRIS DE MARGERIE694A775F6AA36101299050027011200780084201388237770165347926032101700-3301676212757167610972016764455982023/2/14 23:59FOR ORDERS
[23] 后期就是数据的导出,数据预处理之类的啦。

标签: 爬虫 python mysql

本文转载自: https://blog.csdn.net/weixin_50467818/article/details/131423565
版权归原作者 我曾溪底杀指玄 所有, 如有侵权,请联系我们删除。

“AIS数据爬虫---以船讯网为例”的评论:

还没有评论