繁体   English   中英

Python Selenium Scraping Javascript-找不到元素

[英]Python Selenium Scraping Javascript - Element not found

我正在尝试抓取以下Javascript前端网站以练习我的Javascript抓取技能: https : //www.oplaadpalen.nl/laadpaal/112618

我试图通过它们的xPath查找两个不同的元素。 第一个是标题,它确实找到了。 第二个是实际的文本本身,但是找不到。 奇怪,因为我只是从Chrome浏览器复制了xPath。

from selenium import webdriver

link = 'https://www.oplaadpalen.nl/laadpaal/112618'
driver = webdriver.PhantomJS()
driver.get(link)

#It could find the right element
xpath_attribute_title = '//*[@id="main-sidebar-container"]/div/div[1]/div[2]/div/div[' + str(3) + ']/label'
next_page_elem_title = driver.find_element_by_xpath(xpath_attribute_title)
print(next_page_elem_title.text)

#It fails to find the right element
xpath_attribute_value = '//*[@id="main-sidebar-container"]/div/div[1]/div[2]/div/div[' + str(3) + ']/text()'
next_page_elem_value = driver.find_element_by_xpath(xpath_attribute_value)
print(next_page_elem_value.text)

我尝试了几件事:将“ text()”更改为“ text”,“(text)”,但是似乎都没有用。

我有两个问题:

  • 为什么找不到正确的元素?
  • 我们如何做才能使其找到正确的元素?

Selenium的find_element_by_xpath()方法返回与给定XPath查询匹配的第一个元素节点 (如果有)。 但是,XPath的text()函数返回一个文本节点,而不是包含它的元素节点。

要使用Selenium的finder方法提取文本,您需要找到包含元素,然后从返回的对象中提取文本。

我建议一种稍微不同的方法。 我会抓紧整个文本然后分开 : 这将为您提供标题和价值。 下面的代码将通过openstijden标签获取Paalcode。

for x in range(2, 8):
    s = driver.find_element_by_css_selector("div.leftblock > div.labels > div")[x].text
    t = s.split(":", 1)
    print(t[0]) # title
    print(t[1]) # value

您不希望拆分多次,因为状态包含更多的分号。

使用@JeffC的方法,如果要首先使用xpath而不是CSS选择器选择所有这些元素,则可以使用以下代码:

xpath_title_value = "//div[@class='labels']//div[label[contains(text(),':')] and not(div) and not(contains(@class,'toolbox'))]"
title_and_value_elements = driver.find_elements_by_xpath(xpath_title_value)

请注意find_elements_by_xpath方法中的复数元素 上面的xpath选择div元素,它们是div元素的后代,该div元素的类属性为“ labels”。 每个选定的div的嵌套标签必须包含一个冒号。 此外,div本身可能不具有“工具箱”类(页面上某些其他div具有),也不能包含任何其他嵌套的div。

接下来,您可以提取单个div元素(也包含来自嵌套标签元素的文本)中的文本,然后使用“:\\ n”将其分开,从而将标题和值分隔在原始文本字符串中。

for element in title_and_value_elements:
    element = element.text
    title,value = element.split(":\n")
    print(title)
    print(value,"\n")

保持自己的逻辑完整,可以按以下方式提取标签和关联

for x in range(3, 8):
    label = driver.find_element_by_xpath("//div[@class='labels']//following::div[%s]/label" %x).get_attribute("innerHTML")
    value = driver.find_element_by_xpath("//div[@class='labels']//following::div[%s]" %x).get_attribute("innerHTML").split(">")[2]
    print("Label is %s and value is %s" % (label, value))

控制台输出:

Label is Paalcode: and value is NewMotion 04001157
Label is Adres: and value is Deventerstraat 130
Label is pc/plaats: and value is 7321cd Apeldoorn

由于您想练习JS技能,因此您也可以在JS中执行此操作,实际上所有div都包含更多数据,您可以查看是否将其粘贴在浏览器控制台中:

labels = document.querySelectorAll(".labels");
divs = labels[0].querySelectorAll("div");
for (div of divs) console.log(div.firstChild, div.textContent); 

您可以push送到数组并仅检查具有label div并在python变量中返回结果数组:

labels_value_pair.driver.execute_script('''
scrap = [];
labels = document.querySelectorAll(".labels");
divs = labels[0].querySelectorAll("div");
for (div of divs) if (div.firstChild.tagName==="LABEL") scrap.push(div.firstChild.textContent, div.textContent); 
return scrap;
''')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM