Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Selenium驱动程序:通过xpath查找元素;如何解析2级表(即表中的表)_Python_Selenium_Beautifulsoup - Fatal编程技术网

Python Selenium驱动程序:通过xpath查找元素;如何解析2级表(即表中的表)

Python Selenium驱动程序:通过xpath查找元素;如何解析2级表(即表中的表),python,selenium,beautifulsoup,Python,Selenium,Beautifulsoup,我问了一个问题来说明这一点,但由于这是一个具体的不同问题,所以我将其分开,但如果这不是正确的地方,请告诉我 我有这个剧本: from selenium import webdriver from bs4 import BeautifulSoup import os from selenium.webdriver.support.ui import Select from selenium.webdriver.common.by import By from selenium.webdriver.

我问了一个问题来说明这一点,但由于这是一个具体的不同问题,所以我将其分开,但如果这不是正确的地方,请告诉我

我有这个剧本:

from selenium import webdriver
from bs4 import BeautifulSoup
import os
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options


options = Options()
options.binary_location=r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
options.add_experimental_option('excludeSwitches', ['enable-logging'])
driver = webdriver.Chrome(options=options,executable_path='/mnt/c/Users/kela/Desktop/selenium/chromedriver.exe')

#get the url
driver.get('http://147.8.185.62/services/NutriChem-2.0/')


#find the food name
element = driver.find_element_by_id("input_food_name")
element.send_keys("22663")


#click food-disease association
element = Select(driver.find_element_by_css_selector('[name=food_search_section]'))
element.select_by_value('food_disease')


#click submit and click plant-disease associations
driver.find_element_by_css_selector('[value="Submit"]').click()
driver.switch_to.frame(driver.find_element_by_css_selector('frame'))
driver.find_element_by_css_selector('[onclick*="plant-disease"]').click()


#to click into each drop down table rows
driver.switch_to_default_content()
driver.switch_to.frame(driver.find_element_by_name('mainFrame'))
driver.switch_to.frame(driver.find_element_by_name('ListWeb'))
这让我进入了我想要浏览的页面:

下一步,对于每个灰色框,我想拉出(1)PMID,(2)植物,(3)方向(通过图像是up_arrow.png还是down_arrow.png表示,所以只需打印图像名称就可以了)和(4)疾病

从我的上一个问题中可以看出,我对selenium非常陌生,并且认为一旦我进入这一阶段,我将通过表格行循环并使用beautifulSoup打印这些行。我的问题的简短版本是,我就是不能让它工作

我尝试过的事情:

尝试1:

rows = driver.find_elements_by_xpath("//table[@class='Level1Table']//tr[contains(@name,'hList')]")
test_row = rows[0]
print(test_row.text)
上述代码将打印“石榴骨性关节炎3”;但是,我无法解决如何在此循环(我只得到空数据)

尝试2: 然后我试着按行循环遍历每个r,但这仍然只能得到级别1的数据。(即,仅打印多行尝试1)

尝试3:

rows = Select(driver.find_elements_by_xpath("//table[@class='Level2Table']//tr[contains(@name,'hList')]"))
print(rows)
在上面,我想知道为什么我不能运行与尝试1相同的操作,而是通过级别2表而不是级别1循环。此输出为空。我不知道为什么这不起作用;我可以通过查看页面看到level2table在那里

尝试4: 这是我最初考虑的方式,但它不起作用:

for row in rows.findAll('tr'):
        food_source = row.find_all('td')[1].text
        pmid = row.find_all('td')[0].text
        disease = row.find_all('td')[3].text
        #haven't figured out how to get the association direction yet
        print(food_source + '\t' + pmid + '\t' + disease + '\t' + association)
这是我的第一个selenium脚本,所以在这一点上,我只是超出了我的深度。有人能告诉我如何在1级表格中循环2级表格,并提取所需信息(参考、植物、方向和疾病)

编辑1:根据盖伊下面的建议,这是完整的脚本:

from selenium import webdriver
from bs4 import BeautifulSoup
import os
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
import pandas as pd

options = Options()
options.binary_location=r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
options.add_experimental_option('excludeSwitches', ['enable-logging'])
driver = webdriver.Chrome(options=options,executable_path='/mnt/c/Users/kela/Desktop/selenium/chromedriver.exe')

#get the url
driver.get('http://147.8.185.62/services/NutriChem-2.0/')


#find the food name
element = driver.find_element_by_id("input_food_name")
element.send_keys("22663")


#click food-disease association
element = Select(driver.find_element_by_css_selector('[name=food_search_section]'))
element.select_by_value('food_disease')


#click submit and click plant-disease associations
driver.find_element_by_css_selector('[value="Submit"]').click()
driver.switch_to.frame(driver.find_element_by_css_selector('frame'))
driver.find_element_by_css_selector('[onclick*="plant-disease"]').click()


#to click into each drop down table rows
driver.switch_to_default_content()
driver.switch_to.frame(driver.find_element_by_name('mainFrame'))
#driver.switch_to.frame(driver.find_element_by_name('ListWeb'))

#rows = driver.find_elements_by_xpath("//table[@class='Level1Table']//tr[contains(@name,'hList')]")
#test_row = rows[0]

driver.switch_to.frame('ListWeb') # no need for find_element, name or id are sufficient
rows = driver.find_elements_by_css_selector('[id^="ListTAXID"] [name^="Item"]')
for row in rows:
        row_data = row.find_elements_by_xpath('.//td')
        pmid = row_data[0].text
        plant = row_data[1].text
        direction = row_data[2].get_attribute('src')
        disease = row_data[3].text
        print(str(pmid) + '\t' + str(plant) + '\t' + str(direction) + '\t' + str(disease))
这导致了这个输出:

        None
        None
        None
        None
        None
        None
        None
        None
        None
        None
        None
        None

内部表格不是标题行的一部分(带有
'Pomegranate Osteoartritis 3'
文本),而是在不可见的兄弟行中

这些行具有以有助于识别它们的
ListTAXID
开头的
id
属性,并且您要查找的数据位于以
Item
开头的
name
属性的子元素中

仅当表格打开时,文本才可用。您可以在收集数据之前单击所有标题行,或者使用
get_属性('innerText')
而不是
text
,即使表仍然关闭,它也会获取数据

driver.switch_to.frame('ListWeb') # no need for find_element, name or id are sufficient

rows = driver.find_elements_by_css_selector('[id^="ListTAXID"] [name^="Item"]')
for row in rows:
    row_data = row.find_elements_by_xpath('.//td')
    pmid = row_data[0].get_attribute('innerText')
    plant = row_data[1].get_attribute('innerText')
    direction = 'up_arrow' if 'up_arrow' in row_data[2].find_element_by_xpath('.//img').get_attribute('src') else 'down_arrow'
    disease = row_data[3].get_attribute('innerText')

作为旁注,您应该最大化您的窗口
驱动程序。一旦进入要刮取的页面,请最大化\u window()

import pandas as pd

raw = driver.page_source
soup = bs(raw,'lxml')

df = pd.read_html(soup.prettify(),attrs={'class':'Level2Table'})

我认为熊猫将是这里的正确选择。


请共享您希望从中提取数据的表的HTML。谢谢,我可以检查一下这是经过测试的还是未经测试的,因为我得到了:AttributeError:“WebElement”对象没有“find_all”属性?@Slowat_Kela我从您的代码中获取了它。您可以使用
行。改为使用xpath('.//td')
查找元素。请参阅更新的答案。谢谢,我刚刚编辑了我的上述问题,以便添加到您的代码中,如果您可以看到我的问题,输出是什么样的?
# to click into each drop down table rows
driver.switch_to.default_content()
driver.switch_to.frame(driver.find_element_by_name('mainFrame'))
driver.switch_to.frame(driver.find_element_by_name('ListWeb'))

page = BeautifulSoup(driver.page_source, "html.parser")
items = page.select(".Level2Table tr[name^='Item']")
for item in items:
    item_data = item.select("td")
    pmid = item_data[0].text
    plant = item_data[1].text
    direction = "up" if "up_arrow.png" in item_data[2].select_one("img").attrs["src"] else "down"
    disease = item_data[3].text
    print(f"pmid: {pmid}, plant: {plant}, direction: {direction}, disease: {disease}")