我正试着刮出这样的东西。
<ul>
<li> apple <b>price:2.8</b> </li>
<li> orange </li>
<li> banana <b>price:4.3</b> </li>
<li> peach <b>price:2.3</b> </li>
</ul>
有些商品没有价格,也不确定会是哪一种。我需要知道名字和价格。如果它没有价格,那么忽略这条线。
这是我的代码:
name_list = driver.find_elements(By.TAG_NAME, "li")
price_list = driver.find_elements(By.TAG_NAME, "b")
for n in name_list:
name = name_list[n]
price = price_list[n]
错误消息是";IndexError:列表索引超出范围";因为名称和价格的长度不同。
有什么办法可以解决的吗?
<li/>
元素,对结果进行迭代,并对每个元素调用find_elements(…(来查询其子元素。
像这样的东西可以工作:
name_list = driver.find_elements_by_tag_name("li")
for n in name_list:
child = n.find_elements_by_tag_name("b")
// check if it is present, then do stuff
有关详细信息,请查看Selenium文档。
(你也不正确地使用了for…in,它在元素上迭代,而不是在索引上(
这应该能在中工作
fruits = driver.find_elements_by_css_selector('li,b') # finds both elements
for item in fruits: # iterate through list
fruit = item.text # the elements text
if fruit.find('price:') > 0: # consider only those with 'prices'
price =fruit[fruit.find(':')+1:] # just the price value w/o the word 'price'
name = fruit[0:fruit.find('price:')] # just the name of the fruit
print (f'{name}price: {price}') # You may put it into a dictionary instead of printing.
apple price: 2.8
banana price: 4.3
peach price: 2.3
Process finished with exit code 0
下面是一个完整的工作示例,展示了如何获取价格数据:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
driver = webdriver.Firefox()
driver.get("file:///Users/brian/pysel/test_data.html")
name_list = driver.find_elements(By.TAG_NAME, "li")
price_list = driver.find_elements(By.TAG_NAME, "b")
namePriceData = {}
for i, ele in enumerate(name_list):
name = name_list[i]
try:
price = ele.find_element(By.TAG_NAME, "b")
except NoSuchElementException as err:
namePriceData[name.text] = ""
continue
namePriceData[name.text[:len(name.text) - len(price.text)]] = price.text
print(namePriceData)
driver.close()
我们通过在name_list中的每个li
元素上调用find_element
来实现这一点。这允许我们获得元素的子元素。
这个测试数据有点奇怪,因为我们必须获取父元素的文本,然后使用字符串长度将子文本切片。若您遇到具有不同节点结构的真实数据,则在页面上查找这些元素的策略将发生变化。
此外,请注意:
原始代码返回了一个错误,因为它使用了n作为试图索引到元素列表中的键。
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/var/folders/ct/tm9p5wz92dz4l60w9l503f780000gn/T/ipykernel_27037/104717083.py in <module>
6
7 for n in name_list:
----> 8 name = name_list[n]
9 price = price_list[n]
TypeError: list indices must be integers or slices, not WebElement
如果您想以这种方式访问元素,我们需要使用索引而不是实际值进行迭代。在Python中,我们使用enumerate来完成此操作。
由于索引越界错误,使用一个数组的长度索引到另一个数组是错误的,但一旦我们达到一个价格为空的值,它实际上将被分配下一个真正有价格的项目的价格,并且从那时起分配的值是不正确的,直到我们达到索引越界错误。
相反,最好使用实际元素而不是索引进行迭代:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
driver = webdriver.Firefox()
driver.get("file:///Users/brian/pysel/test_data.html")
name_list = driver.find_elements(By.TAG_NAME, "li")
price_list = driver.find_elements(By.TAG_NAME, "b")
namePriceData = {}
for ele in name_list:
try:
price = ele.find_element(By.TAG_NAME, "b")
except NoSuchElementException as err:
namePriceData[ele.text] = ""
continue
namePriceData[ele.text[:len(ele.text) - len(price.text)]] = price.text
print(namePriceData)
driver.close()