从Python脚本获取三重输出

从Python脚本获取三重输出,python,pandas,gpx,Python,Pandas,Gpx,对Python来说非常陌生-我正在修改我找到的一个脚本,这样我就可以从一个站点抓取位置信息,转换成.gpx,然后在导航软件中使用。我设法让一切正常工作,我只得到了三次输出!有人能告诉我为什么会发生这种事吗?我相信这是很明显的,但我一点也不明白 代码如下: from selenium import webdriver from bs4 import BeautifulSoup import pandas as pd import re from time import gmtime, strfti

对Python来说非常陌生-我正在修改我找到的一个脚本,这样我就可以从一个站点抓取位置信息,转换成.gpx,然后在导航软件中使用。我设法让一切正常工作,我只得到了三次输出!有人能告诉我为什么会发生这种事吗?我相信这是很明显的,但我一点也不明白

代码如下:

from selenium import webdriver
from bs4 import BeautifulSoup
import pandas as pd
import re
from time import gmtime, strftime
import dateutil.parser as dparser
from dateutil import tz
from datetime import timezone

driver = webdriver.Chrome("chromedriver")
skippers=[]
rankings=[]
latitudes=[]
longitudes=[]

driver.get("https://www.vendeeglobe.org/en/ranking")

content = driver.page_source
soup = BeautifulSoup(content, "html.parser")

# get time of position of report and do some stuff to make sure it is recognised as 24hour clock and UTC
filetime = soup.find('p', class_=('rankings__subtitle'))
# print(filetime)
filetime  = re.sub(r"[h\(\)]+", ' ', filetime.text)
# print(filetime)
filetime = dparser.parse(filetime, fuzzy=True)
# print(filetime)
filetime = filetime.strftime("%y%m%d%H%M")


# find the entries for each boat and interate through them extracting what we want
for a in soup.findAll('div', attrs={'class':'rankings__item'}):
    name=a.find('span', attrs={'style':'max-width: 140px;'})  # boat name
    ranking=a.find('li', attrs={'class':'rankings__number'})  # current postion in fleet
 # the location of lat and lon is not obvious, and nested, so locate by the position of respective LI
    list = a.findAll('li')[6]
    lat = list.findAll('span')[1]
    lon = list.findAll('span')[2]
# Convert lat and lon to strings and strip  special characters    
    lat = re.sub(r"\W+|_", " ", lat.text)
    lon = re.sub(r"[^a-zA-Z0-9]+", ' ', lon.text)
    # covert degrees mins and seconds to decimal degrees
    deg, minutes, seconds, direction =  re.split('[ ]', lat)
    lat = (float(deg) + float(minutes)/60 + float(seconds)/(60*60)) * (-1 if direction in ['O', 'S'] else 1)
    lat = round(lat, 4)
    deg, minutes, seconds, direction =  re.split('[ ]', lon)
    lon = (float(deg) + float(minutes)/60 + float(seconds)/(60*60)) * (-1 if direction in ['O', 'S'] else 1)
    lon = round(lon, 4)
# Append the boats numbers to the  list 
    skippers.append(name.text)
    rankings.append(ranking.get_text(strip=True))
    latitudes.append(lat)
    longitudes.append(lon)

# create a pandas data frame
    df = pd.DataFrame({'id':skippers,'latitude':latitudes,'longitude':longitudes})

# Format information
def to_gpx(df, filename=None, mode='w'):
    def row_to_gpx(row):
        xml = ['<gpx>']
        for i, row in df.iterrows():
            xml.append('<wpt lat="{0}" lon="{1}"><name>{2}</name></wpt>'.format(latitudes[i], longitudes[i], skippers[i]))
        xml.append('</gpx>')
        return '\n'.join(xml)
    res = '\n'.join(df.apply(row_to_gpx))

# Output to .gpx
    if filename is None:
        return res
    with open(filename, mode) as f:
          f.write(res)

pd.DataFrame.to_gpx = to_gpx

df.to_gpx('Scheds_'+filetime+'.gpx')
从selenium导入webdriver
从bs4导入BeautifulSoup
作为pd进口熊猫
进口稀土
从时间导入gmtime,strftime
将dateutil.parser作为dparser导入
从dateutil导入
从日期时间导入时区
driver=webdriver.Chrome(“chromedriver”)
船长=[]
排名=[]
纬度=[]
经度=[]
驱动程序。获取(“https://www.vendeeglobe.org/en/ranking")
content=driver.page\u来源
soup=BeautifulSoup(内容为“html.parser”)
#获取报告位置的时间,并做一些事情以确保它被识别为24小时时钟和UTC
filetime=soup.find('p',class=('rankings\uuuu subtitle'))
#打印(文件时间)
filetime=re.sub(r“[h\(\)]+”,“”,filetime.text)
#打印(文件时间)
filetime=dparser.parse(filetime,fuzzy=True)
#打印(文件时间)
filetime=filetime.strftime(“%y%m%d%H%m”)
#找到每艘船的条目,并通过它们进行交互,提取我们想要的内容
对于一个在soup.findAll('div',attrs={'class':'rankings\uuuu item'})中的项目:
name=a.find('span',attrs={'style':'max-width:140px;'})#船名
排名=a.find('li',attrs={'class':'rankings\uu number'})#目前在舰队中的位置
#lat和lon的位置不明显,且嵌套,因此根据各自LI的位置进行定位
list=a.findAll('li')[6]
lat=list.findAll('span')[1]
lon=list.findAll('span')[2]
#将lat和lon转换为字符串并去除特殊字符
lat=re.sub(r“\W+|,”,lat.text)
lon=re.sub(r“[^a-zA-Z0-9]+”,“”,lon.text)
#将度数分和秒转换为十进制度数
度,分,秒,方向=重新拆分(“[]”,纬度)
横向=(浮动(度)+浮动(分)/60+浮动(秒)/(60*60))*(-1如果方向为['O','S'],则为1)
横向=圆形(横向,4)
度,分,秒,方向=重新拆分(“[]”,lon)
lon=(浮动(度)+浮动(分钟)/60+浮动(秒)/(60*60))*(-1如果方向为[O',S',否则1)
lon=圆形(lon,4)
#将船号附加到列表中
skippers.append(name.text)
rankings.append(ranking.get_text(strip=True))
纬度。附加(纬度)
经度。附加(lon)
#创建一个数据帧
df=pd.DataFrame({'id':跳过,“纬度”:纬度,'经度”:经度})
#格式信息
def to_gpx(df,filename=None,mode='w'):
def行_至_gpx(行):
xml=['']
对于i,df.iterrows()中的行:
append(“{2}.”格式(纬度[i]、经度[i]、跳跃[i]))
xml.append(“”)
返回'\n'。加入(xml)
res='\n'.join(df.apply(行\u到\u gpx))
#输出到.gpx
如果文件名为“无”:
返回res
打开(文件名、模式)为f时:
f、 写入(res)
pd.DataFrame.to_gpx=to_gpx
df.to_gpx('Scheds_'+filetime+'.gpx'))
我得到的结果大致如下:

<gpx>
<wpt lat="000000" lon="000000"><name>Name</name></wpt>
<wpt lat="000000" lon="000000"><name>Name</name></wpt>
<wpt lat="000000" lon="000000"><name>Name</name></wpt>
<wpt lat="000000" lon="000000"><name>Name</name></wpt>
</gpx>
<gpx>
<wpt lat="000000" lon="000000"><name>Name</name></wpt>
<wpt lat="000000" lon="000000"><name>Name</name></wpt>
<wpt lat="000000" lon="000000"><name>Name</name></wpt>
<wpt lat="000000" lon="000000"><name>Name</name></wpt>
</gpx>
<gpx>
<wpt lat="000000" lon="000000"><name>Name</name></wpt>
<wpt lat="000000" lon="000000"><name>Name</name></wpt>
<wpt lat="000000" lon="000000"><name>Name</name></wpt>
<wpt lat="000000" lon="000000"><name>Name</name></wpt>
</gpx>

名称
名称
名称
名称
名称
名称
名称
名称
名称
名称
名称
名称
我希望gpx标签之间只有一个航路点块,但我得到了三个


谢谢大家。

我建议试着运行刮片部分,您可能会从该站点获得三份结果副本。顺便问一下,你是如何运行脚本的?嘿!我只运行了抓取部分,并将其打印到控制台上——在抓取网站时,我会得到每次迭代的数据。有33位数据,因此它运行33次,每次添加下一个数据点。我从Macosi上的终端运行它,如果刮片部件只输出一次,然后将其保存到一个文件中,并用该负载替换所有刮片部件。以相同的方式收缩代码,直到找到错误为止。我建议试着运行刮片部分,你可能会从网站上得到三份结果。顺便问一下,你是如何运行脚本的?嘿!我只运行了抓取部分,并将其打印到控制台上——在抓取网站时,我会得到每次迭代的数据。有33位数据,因此它运行33次,每次添加下一个数据点。我从Macosi上的终端运行它,如果刮片部件只输出一次,然后将其保存到一个文件中,并用该负载替换所有刮片部件。以相同的方式收缩代码,直到找到错误为止。看起来不像是什么突出我的东西。