如何单击元素并从链接的 xml 文件(python)中解析文本?
Posted
技术标签:
【中文标题】如何单击元素并从链接的 xml 文件(python)中解析文本?【英文标题】:How to click on an element and parse text from linked xml file (python)? 【发布时间】:2021-11-11 06:36:51 【问题描述】:我想从以下网站解析地址:https://filialen.migros.ch/de/center:46.8202,6.9575/zoom:8/
到目前为止,我可以访问该网站并单击任何弹出窗口。但是我需要选择带有“1163 STANDORTE”的下拉菜单,我无法用我的代码找到它。 到目前为止我的代码:
import pandas as pd
import requests
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select
from bs4 import BeautifulSoup
import time
import itertools
import os
import numpy as np
import csv
import pdb
os.chdir("Directory")
options = webdriver.ChromeOptions()
options.add_argument("--incognito")
driver = webdriver.Chrome('Directory/chromedriver.exe')
driver.get("https://filialen.migros.ch/de/center:46.8202,6.9575/zoom:8/")
time.sleep(1)
try:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//*[@class='close-icon']"))).click() # if there is smth to click away
except:
pass
time.sleep(4)
然后我尝试使用 span 和 button 元素以及几个导航选项:
#Version 1
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[@class='sc-hKFxyN jdMjfs']"))).click()
#Version 2
element = driver.find_element_by_class_name('sc-eCApnc kiXUNl sc-jSFjdj lcZmPE')
driver.execute_script("arguments[0].scrollIntoView();", element)
driver.execute_script("arguments[0].click();", element)
# Version 3
element = driver.find_element_by_class_name('sc-eCApnc kiXUNl sc-jSFjdj lcZmPE')
driver.execute_script("arguments[0].click();", element)
#Version 4
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//*[@class='sc-eCApnc kiXUNl sc-jSFjdj lcZmPE']"))).click()
# Version 5
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[2]/div/main/nav/header/button[1]"))).click()
# Version 6
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[text()='1163 STANDORTE']"))).click()
其实存在三个问题:
-
如果我只是手动打开 Chrome 上的链接,则会出现“1163 STANDORTE”,而如果我使用 python 在 Chrome 上打开链接,会出现较少的 STANDORTE,但我无法缩小。所以我非常需要 ALL 1163 STANDORTE 出现。
我无法使用类和 XPATH 找到按钮。
按钮后面是一个可能链接的XML文件,地址信息只有在单击按钮后才会出现。最后,我想抓取文本,写在链接到该按钮的 XML 文件上。
有什么建议吗?
我的问题与之前的问题类似:How to parse several attributes of website with same class name in python? 和Selenium-Debugging: Element is not clickable at point (X,Y)
【问题讨论】:
【参考方案1】:几点:
启动 browser in full screen mode.
使用显式等待。
使用这个 xpath //span[contains(@aria-label, 'Standorte anzeigen')]/..
示例代码:
driver = webdriver.Chrome(driver_path)
driver.maximize_window()
#driver.implicitly_wait(50)
wait = WebDriverWait(driver, 20)
driver.get("https://filialen.migros.ch/de/center:46.8202,6.9575/zoom:8/")
try:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//*[@class='close-icon']"))).click() # if there is smth to click away
except:
pass
wait.until(EC.element_to_be_clickable((By.XPATH, "//span[contains(@aria-label, 'Standorte anzeigen')]/.."))).click()
进口:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
PS:如果我们在HTML DOM
中有唯一条目,请检查dev tools
(谷歌浏览器)。
检查步骤:
Press F12 in Chrome
-> 转到element
部分 -> 做一个CTRL + F
-> 然后粘贴xpath
看看,如果你想要的element
用@ 得到突出显示 987654333@匹配节点。
【讨论】:
感谢@cruisepandey 这行得通。但是您能否详细说明您是如何知道这一点的:“//span[contains(@aria-label, 'Standorte anzeigen')]/..”?理解底层机制对我(和其他人)有很大帮助。 @tiny : 用chrome打开开发工具,基本上就是xpath
,看到HTML后就可以自己构建自定义的xpath了。请参阅此处w3schools.com/xml/xpath_axes.asp 以了解有关 xpath 的更多信息。
@ Cruisepaney:我试过这个(使用 CTRL-Shift-I),但在那里我只能找到 class ="sc-eCApnc kiXUNl sc-jSFjdj lcZmPE"
的按钮,我尝试使用 xpath
导航到该按钮,但这是不可能的.我可以看到你的xpath
,例如html中没有“Standorte anzeigen”,所以我可能看错了地方。你到底是在哪里找到的?
见上面我已经更新了如何检查元素。
@cruisepandey:好的,非常感谢更新!我仍然不明白为什么使用上面指定的类我无法使用xpath
导航到按钮。【参考方案2】:
您要查找的数据基于fetch
/ xhr
调用。
无需抓取即可获得。见下文。
import requests
headers = 'Origin': 'https://filialen.migros.ch',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36'
r = requests.get(
'https://web-api.migros.ch/widgets/stores?key=loh7Diephiengaiv&aggregation_options[empty_buckets]=true&filters[markets][0][0]=super&filters[markets][0][1]=mno&filters[markets][0][2]=voi&filters[markets][0][3]=mp&filters[markets][0][4]=out&filters[markets][0][5]=spx&filters[markets][0][6]=doi&filters[markets][0][7]=mec&filters[markets][0][8]=mica&filters[markets][0][9]=res&filters[markets][0][10]=flori&filters[markets][0][11]=gour&filters[markets][0][12]=alna&filters[markets][0][13]=cof&filters[markets][0][14]=chng&verbosity=store&offset=0&limit=5000',
headers=headers)
if r.status_code == 200:
print('stores data below:')
data = r.json()
print(data)
else:
print(f'Oops. Statud code is r.status_code')
【讨论】:
谢谢@balderman,这行得通。但是你是怎么知道api文档的呢?这将有助于解决未来的类似问题。 在浏览器中执行:F12 -- Network -- XHR 并查看页面为获取数据而执行的 http 调用。随意接受答案。 我很抱歉,但我会接受另一个答案,因为它更专注于回答我的实际问题,即使你的回答让我更快地达到最终目标。不过我也赞成你的!以上是关于如何单击元素并从链接的 xml 文件(python)中解析文本?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 app.config 中提供 xml 文件源并从 winform 中写入/读取这些 xml 文件?
Python:从可单击的链接下载文件,单击该链接开始下载文件