如何从动态网站python selenium中检索表

Posted

技术标签:

【中文标题】如何从动态网站python selenium中检索表【英文标题】:How to retrieve table from dynamic website python selenium 【发布时间】:2019-08-07 04:33:30 【问题描述】:

我想从动态网站上的表格中检索所有信息,我有以下代码:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
import sys
reload(sys)
import re
import csv
from time import sleep
sys.setdefaultencoding('utf-8') #added since it would give error for certain values when using str(i)

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
prefs = 'profile.managed_default_content_settings.images':2
chrome_options.add_experimental_option("prefs", prefs)
driver = webdriver.Chrome(chrome_options=chrome_options) 

maxcr = 1379
listofrows = []


url = "http://biggestbook.com/ui/catalog.html#/itemDetail?itemId=HERY4832YER01&uom=CT"
print(url) 
driver.get(url)
wait = WebDriverWait(driver,10)
# Trying to get the table 
tableloadwait = (wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".panel-body"))))
table = driver.find_elements_by_css_selector(".panel-body")
print(table)
RowsOfTable = table.get_attribute("tr")

但是,我不断收到错误消息,但到目前为止它不起作用。如何检索表的信息? 非常感谢!

错误: RowsOfTable = table.get_attribute("tr") AttributeError: 'list' 对象没有属性 'get_attribute'

【问题讨论】:

错误是什么,发生在哪里? 总是显示有问题的完整错误(Traceback)。 您将收到AttributeError: 'list' object has no attribute 'get_attribute' 错误,因为tr 不是属性。你想从表中获取什么数据? find_elements_ (s in elements) 总是给出包含许多元素的列表 - 所以你必须使用 for 循环来获取每个元素并单独使用 get_attribute 和每个元素. 错误:RowsOfTable = table.get_attribute("tr") AttributeError: 'list' object has no attribute 'get_attribute' 【参考方案1】:

这是获取产品详细信息的代码

tableloadwait = (wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".panel-body"))))
driver.find_element_by_xpath("//span[contains(.,'Product Details')]").click()
rows = driver.find_elements_by_xpath("//span[contains(.,'Product Details')]/ancestor::div[@class='accordion-top-border']//tr[(@ng-repeat='attr in attributes' or @ng-repeat='field in fields') and @class='visible-xs']")

for rowNum in range(len(rows)):
    print(rows[rowNum].get_attribute('innerText'))
driver.quit()

我们必须根据您的要求修剪值或破坏值。

如果您想根据行文本获取数据,请使用以下内容。

upcData = driver.find_element_by_xpath("//strong[.='UPC']/parent::td").get_attribute('innerText').replace('UPC','').replace('\n','').replace('    ','')

【讨论】:

在这里,我实际上想要获取产品详细信息而不是 6 个表格。我以为 (".panel-body") 只适用于该表? 这里有没有办法从这个表中只获取“全球产品类型”? 使用您的第一个解决方案,我只能将表格设置为“特殊功能”。如果我想获得以下任何一个属性,那么我需要做什么?例如,如果我想要 UPC 或 UNSPSC 而不是“全球产品类型”?因为当我将以下任何内容(纸箱重量纸箱包装数量 UPC UNSPSC)放在上面的代码(来自注释的代码)中时,它会给出一个空白。如果我运行您提供的第一个代码,那么这些不会显示,但会显示其他属性。我现在有点迷茫 @suppurturi 是的,我也这样做了。但是,将零件替换为“UPC”或 UNSPSC 都会给出空白。事实上,即使我运行您为整个表格提供的第一个代码,这些特定的代码以及其他一些属性也不会显示出来。他们没有出现的任何原因? 在聊天中给你发了一条消息!【参考方案2】:

首先使用适当的 + 按钮展开手风琴,然后选择表格。添加等待项目出现。如果您想要另一个表,请将 expandSigns 索引更改为 2。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import pandas as pd

url = 'http://biggestbook.com/ui/catalog.html#/itemDetail?itemId=HERY4832YER01&uom=CT'
driver = webdriver.Chrome()
driver.get(url)
expandSigns = WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".glyphicon-plus")))
expandSigns[1].click()
WebDriverWait(driver,10).until(EC.presence_of_element_located((By.CSS_SELECTOR, "td")))

table = driver.find_element_by_css_selector('table')
html = table.get_attribute('outerHTML')

df  = pd.read_html(html)
print(df)
driver.quit()

【讨论】:

我想将输出写入文件,但它将所有内容都放在一个单元格中,但我希望它位于不同的行中。现在我对发生了什么感到困惑。 df = pd.read_html(html) print(html) listofrows.append(df) print(listofrows) for rows in listofrows: with open('listofData.csv', 'w') as listofData: for rows in listofrows: rowlistwriter = csv.writer(listofData) rowlistwriter.writerow(rows) 另外,我不想打开 chrome(使用您的方法),但由于某种原因,它仍然会打开并饱和所有内容chrome_options = webdriver.ChromeOptions() chrome_options.add_argument('--headless') driver = webdriver.Chrome(chrome_options=chrome_options) 为什么不使用 df.to_csv?至于无头不知道为什么这不起作用。快速浏览一下,您所写的内容看起来是正确的。我必须测试。 正如你所建议的,我做了以下事情: df[0].to_csv("output.csv") 并且它有效。但是如何将其转换为列?它给出行 atm 另外,如果我继续喂多个页面,它会继续写入新行吗?【参考方案3】:

如果你需要抓取而不是测试,你可以使用 requests 来获取数据。下面的代码是如何从页面获取数据的示例。

import requests
import re

# Return header page(html) to get token and list key
response = requests.get("http://biggestbook.com/ui/catalog.html#/itemDetail?itemId=HERY4832YER01&uom=CT")

# Get token using regular expression
productRecommToken = re.search("'productRecommToken','(.+)'", response.text)[1]

# Get list of keys using regular expression
listKey = re.search("'listKey',\\['(.*?)'\\]", response.text)[1].split("','")

# Create header with token
headers = 
    'Accept': 'application/json, text/plain, */*',
    'Referer': 'http://biggestbook.com/ui/catalog.html',
    'Origin': 'http://biggestbook.com',
    'DNT': '1',
    'token': productRecommToken,
    'BiggestBook-Handle-Errors-Generically': 'true',


# Create parameters with list keys and search values
params = (
    ('listKey', listKey),
    ('uom', 'CT'),
    ('vc', 'n'),
    ('win', 'HERY4832YER01'),
)

# Return json with all details about product
response = requests.get('https://api.essendant.com/digital/digitalservices/search/v1/items',
                       headers=headers,
                       params=params)
data = response.json()

# Get items from json, probably could be more than one
items = data["items"]

# Iterate and get details you need. Check "data" to see all possible details you can get
for i in items:
    print(i["manufacturer"])
    print(i["description"])
    print(i["actualPrice"])

    # Get attributes
    attributes = i["attributes"]

    # Example hot you can get specific one attribute.
    thickness = list(filter(lambda d: d['name'] == 'Thickness', attributes))[0]["value"]

    # Print all attributes as name = value
    for a in attributes:
        print(f"a['name'] = a['value']")

【讨论】:

以上是关于如何从动态网站python selenium中检索表的主要内容,如果未能解决你的问题,请参考以下文章

Python Selenium 无法从 mpob 网站检索标签内容

如何使用 Selenium 和 Python 从文本节点中检索部分文本

如何在 selenium 中更快地从动态网站读取数据

需要有关从动态网站检索站点密钥的帮助

使用 Selenium 和 Python 进行用户输入的网页抓取动态网站

Python + Selenium firefox webdriver - 从网站中提取图像