关于某06火车站字典的获取与保存

打算爬取一下某06的车次信息,发现在车次请求的Request URL中出发地与目的地均采用了站点的三字码而非汉字,所以只能先去获取站点三字码。

获取网址:三字码网址

打开后的样式如图:
关于某06火车站字典的获取与保存_第1张图片

可以很轻易的看出每个站点数据的开头均为‘@’故而可以先用split(’@’)将所有站点数据拆分开。

拆分后格式为:

'拼音简写|站点中文名|三字码|拼音全写|拼音简写|序号'

根据拆分后的格式,可运用re库提供的两种方法对想要数据进行提取。

  1. findall方法
  2. match方法

第一种方法:

import re
import requests
city_list = []
data_city = requests.get('https://www.12306.cn/index/script/core/common/station_name_v10037.js')
data_city = data_city.text
data_city_list = data_city.split('@')
print(data_city_list)
for i in range(1,len(data_city_list)):
    a = re.findall ( '(\w{3,5})\|(.{2,5})\|(\w{3,5})', data_city_list[i] )
    city_list.append(a)

其中注意,若应用findall方法会匹配到所有符合要求的数据,也就会导致从第100个数据开始变成如下所示样式

[('bto', '包头', 'BTC'), ('aotou', 'bt', '100')]
[('bts', '北屯市', 'BXR'), ('unshi', 'bts', '101')]
[('bxi', '本溪', 'BXT'), ('benxi', 'bx', '102')]
[('byb', '白云鄂博', 'BEC'), ('unebo', 'byeb', '103')]
[('byx', '白银西', 'BXJ'), ('yinxi', 'byx', '104')]
[('bzh', '亳州', 'BZH'), ('ozhou', 'bz', '105')]
[('cbi', '赤壁', 'CBN'), ('chibi', 'cb', '106')]
[('cde', '常德', 'VGQ'), ('angde', 'cd', '107')]
[('cde', '承德', 'CDP'), ('engde', 'cd', '108')]
[('cdi', '长甸', 'CDT'), ('gdian', 'cd', '109')]
[('cfe', '赤峰', 'CFD'), ('ifeng', 'cf', '110')]
[('cli', '茶陵', 'CDG'), ('aling', 'cl', '111')]
[('cna', '苍南', 'CEH'), ('ngnan', 'cn', '112')]

其具体原因是从序号100开始的车站数据序号位长度大于3满足了正则式中的\w{3,5}。
所以若使用findall方法必须在倒数第二行代码的末尾处加入’[0]’。

a = re.findall ( '(\w{3,5})\|(.{2,5})\|(\w{3,5})', data_city_list[i] )[0]

或者更改正则式为'(\w{3,5})\|(.{2,5})\|([a-zA-z]{3,5})'
第二种方法:

import re
import requests
city_list = []
data_city = requests.get(url_headers.url_12306_citydict)
data_city = data_city.text
data_city_list = data_city.split('@')
for i in range(1,len(data_city_list)):
    a = re.match ( '(\w){3,5}\|(.){2,5}\|(\w){3,5}', data_city_list[i] )
    city_list.append(a)
    

与findall方法不同match方法从每个字符串的起始位置开始匹配,在匹配成功一次后即结束匹配,这样会避免上述情况的发生,但会引来一个新的问题。

<re.Match object; span=(0, 11), match='bjb|北京北|VAP'>
<re.Match object; span=(0, 11), match='bjd|北京东|BOP'>
<re.Match object; span=(0, 10), match='bji|北京|BJP'>
<re.Match object; span=(0, 11), match='bjn|北京南|VNP'>
<re.Match object; span=(0, 11), match='bjx|北京西|BXP'>
<re.Match object; span=(0, 11), match='gzn|广州南|IZQ'>
<re.Match object; span=(0, 11), match='cqb|重庆北|CUW'>
<re.Match object; span=(0, 10), match='cqi|重庆|CQW'>
<re.Match object; span=(0, 11), match='cqn|重庆南|CRW'>
<re.Match object; span=(0, 11), match='cqx|重庆西|CXW'>
<re.Match object; span=(0, 11), match='gzd|广州东|GGQ'>
<re.Match object; span=(0, 10), match='sha|上海|SHH'>
<re.Match object; span=(0, 11), match='shn|上海南|SNH'>

match方法获取到的数据的数据类型并非列表,而是re.Match,在后期应用时不太方便。所以需要由re.Match类型转换为列表或其他数据类型,需要再次使用findall方法。既最后一行改成如下代码:

city_list.append(re.findall(',str(a)))

至此,全部的火车站三字码已获取,接下来将利用xlwt库对获取到的数据存储为表格文件。

import xlwt
i = 0
wb = xlwt.Workbook()
sheet1 = wb.add_sheet(u'sheet1', cell_overwrite_ok=True)
for j1 in city_list:
    sheet1.write ( i, 0, city_list[ i ][ 0 ][ 0 ] )
    sheet1.write ( i, 1, city_list[ i ][ 0 ][ 1 ] )
    sheet1.write ( i, 2, city_list[ i ][ 0 ][ 2 ] )
    i+=1
wb.save ( './city_list.xlsx' )

最后生成的city_list.xlsx文件的部分内容如图:
关于某06火车站字典的获取与保存_第2张图片

你可能感兴趣的:(爬虫,python,正则表达式)