我为一个小组工作,该小组希望在Tx中提取端口状态的自动报告。为此,我正在尝试抓取海岸警卫队Homeport网站(我不太熟悉)。我设法使用Selenium通过带有端口的页面表的xpath提取所有信息,但是脚本的“表2”上有一个端口(维多利亚),脚本无法看到。如果我在页面之间切换,则xpath不会更改,因此我不确定如何找到它。任何帮助将不胜感激!
编辑:该页面使用Javascript元素。
https://homeport.uscg.mil/port-directory/corpus-christi
url = 'https://homeport.uscg.mil/port-directory/corpus-christi'
xpath= "/html/body/form/div[12]/div[2]/div[2]/div[2]/div[3]/div[1]/div[4]/div/div/div/div/div/div[1]/div/div[2]/div[1]/div/div/div[2]/div/div[2]/div/table"
portsList = ['CORPUS CHRISTI','ORANGE','BEAUMONT','VICTORIA','CALHOUN','HARLINGEN','PALACIOS','PORT ISABEL','PORT LAVACA','PORT MANSFIELD']
df = pd.DataFrame(index=portsList, columns=['status','comments','dateupdated'])
driver = webdriver.Chrome(executable_path = r"C:\Users\M3ECHJJJ\Documents\chromedriver.exe")
urlpage = url+page
driver.get(urlpage)
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);var lenOfPage=document.body.scrollHeight;return lenOfPage;")
time.sleep(15)
results = driver.find_elements_by_xpath(xpath)
ports_split = results[0].text.split('\n')
i = 0
for port in ports_split:
if port.upper() in portsList:
print(port)
df.xs(port.upper())['status'],df.xs(port.upper())['comments'],df.xs(port.upper())['dateupdated'] = parsePara(ports_split[i+1])
i = i+1
driver.quit()
答案 0 :(得分:0)
首先,要非常小心地编写与政府网站(或与此有关的任何网站)相抵触的自动化程序,并确保您被允许这样做。您可能还会发现,许多网站都以结构化格式(例如通过API或数据下载)提供您正在寻找的信息。
尽管selenium
为您提供了一个使浏览器实现自动化的出色工具,但其定位元素和解析HTML的功能可能还有很多不足之处。在这种情况下,我可能会使用BeautifulSoup
作为与浏览器自动化一起使用的补充工具。
BeautifulSoup将支持与硒相同的所有定位器,但还提供其他功能,包括定义自己的元素定位标准的功能。
例如,您可以定义一个函数以使用非常特定的规则来定位元素(标签)。该函数应返回True
以查找符合您兴趣的标签。
from bs4 import BeautifulSoup
def important_table(tag):
"""Given a particular tag, return True if it's what you're looking for"""
return bool(
# match <table> elements
tag.name == 'table' and
# check for expected text
any(port_name in tag.text for port_name in portsList) and
# check element attributes
"classname" in tag.get('class', []) and
# has at least 3 rows
len(tag.findall('tr')) > 3
# and so on
)
这只是一个示例,但是您可以根据需要编写此函数。
然后您可以这样应用
...
driver.get(urlpage)
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);var lenOfPage=document.body.scrollHeight;return lenOfPage;")
time.sleep(15)
html = driver.page_source # get the DOM content as a string
soup = BeautifulSoup(html)
table = soup.find(important_table)
for row in table.findall('tr'):
print(row.text)