Python 使用selenium查找div中的索引元素

Python 使用selenium查找div中的索引元素,python,selenium,indexing,web-scraping,beautifulsoup,Python,Selenium,Indexing,Web Scraping,Beautifulsoup,我正在抓取一个网页的前端,很难在一个div中获取div的HMTL文本 基本上,我是在模拟点击——页面上列出的每个事件一次。从那里,我想抓取事件的日期和时间,以及事件的地点 下面是一个我正在努力抓取的页面示例: 这张照片是: Event information: Sunday, April 21st, 2019 3:00 PM San Francisco Brewing Co. 3150 Polk St, Sf, CA 94109 View All The Fourth Son Tour Dat

我正在抓取一个网页的前端,很难在一个div中获取div的HMTL文本

基本上,我是在模拟点击——页面上列出的每个事件一次。从那里,我想抓取事件的日期和时间,以及事件的地点

下面是一个我正在努力抓取的页面示例:

这张照片是:

Event information: Sunday, April 21st, 2019
3:00 PM
San Francisco Brewing Co.
3150 Polk St, Sf, CA 94109
View All The Fourth Son Tour Dates
我的问题是无法单独访问嵌套的eventInfoContainer div。例如,“date”div是位置[1],因为它是其父div“eventInfoContainer-9E53994”中的第二个元素(在img之后)。父div“eventInfoContainer-9E53994”位于位置[1],它同样是其父div“eventInfoContainer-54d5deb3”(在“lineupContainer”之后)中的第二个元素

按照这种逻辑,我是否应该能够通过以下代码访问日期文本:(访问容器中的第一个位置元素,其父元素是第一个位置元素(第0个位置元素)

我得到以下错误:

TypeError: 'WebElement' object does not support indexing

感谢您的帮助!提前谢谢。

当您索引到webElements列表(即
find\u elements\u by\u css\u selector('div[class^=eventInfoContainer-]')时,
返回)您得到一个webElement,您无法进一步索引到该列表中。您可以拆分webElement的文本以生成一个列表以进行进一步索引

如果页面之间存在规则结构,则可以将div的html加载到BeautifulSoup中。示例url:

from selenium import webdriver
from bs4 import BeautifulSoup as bs

d = webdriver.Chrome()
d.get('https://www.bandsintown.com/e/1013664851-los-grandes-de-la-banda-at-aura-nightclub?came_from=257&utm_medium=web&utm_source=home&utm_campaign=event')
soup = bs(d.find_element_by_css_selector('[class^=eventInfoContainer-]').get_attribute('outerHTML'), 'lxml')
date = soup.select_one('img + div').text
time = soup.select_one('img + div + div').text
venue = soup.select_one('[class^=eventInfoContainer-]:nth-of-type(3) div > div').text
address = soup.select_one('[class^=eventInfoContainer-]:nth-of-type(3) div + div').text

print(date, time, venue, address)

如果换行符一致:

containers = d.find_elements_by_css_selector('div[class^=eventInfoContainer-]')
array = containers[0].text.split('\n')
date = array[3]
time = array[4]
venue = array[5]
address = array[6]
print(date, time, venue, address)

使用索引和拆分:

from selenium import webdriver
from bs4 import BeautifulSoup as bs

d = webdriver.Chrome()
d.get('https://www.bandsintown.com/e/1013664851-los-grandes-de-la-banda-at-aura-nightclub?came_from=257&utm_medium=web&utm_source=home&utm_campaign=event')
containers = d.find_elements_by_css_selector('div[class^=eventInfoContainer-]')
date_time = containers[1].text.split('\n')
i_date = date_time[0]
i_time = date_time[1]
venue_address = containers[3].text.split('\n')
venue = venue_address[0]
address = venue_address[1]
print(i_date, i_time, venue, address)

正如错误所暗示的那样,webelements没有索引。你混淆的是列表

这里

driver.find_elements_by_css_selector('div[class^=eventInfoContainer-]')
此代码返回webelement的列表。这就是为什么您可以使用列表的索引访问webelement。但该元素没有对其他webelement的索引。您无法获得列表列表

这就是为什么
driver.find\u elements\u by\u css\u selector('div[class^=eventInfoContainer-])[0]
有效。但是
driver.find\u elements\u by\u css\u selector('div[class^=eventInfoContainer-][0][1]')
无效


编辑:(回答评论中的问题)


它不是slenium代码

回答中发布的代码使用了
BeautifulSoup
。它是一个用于解析HTML和XML文档的python包。
BeautifulSoup
有一个
.select()
方法,该方法对已解析的文档使用CSS选择器并返回所有匹配的元素。
还有一个名为
select_one()
的方法,它只查找与选择器匹配的第一个标记

在守则中,

time = soup.select_one('img + div + div').text 
venue = soup.select_one('[class^=eventInfoContainer-]:nth-of-type(3) div > div').tex
它获取给定CSS选择器找到的第一个元素并返回标记内的文本。第一行查找
img
标记,然后查找直接同级
div
标记,然后再次查找上一个
div
标记的同级开发标记。 在第二行中,它找到类以
eventInfoContainer-
开头的第三个同级标记,然后找到子
div
并找到该
div
的子级

退房

这可以直接使用selenium完成:

date = driver.find_element_by_css_selector("img[class^='eventInfoContainer-'][src$='clock.svg'] + div")
time = driver.find_element_by_css_selector("img[class^='eventInfoContainer-'] + div + div")
venue = driver.find_element_by_css_selector("img[class^='eventInfoContainer-'][src$='pin.svg'] + div > div")
address = driver.find_element_by_css_selector("img[class^='eventInfoContainer-'][src$='pin.svg'] + div > div:nth-of-type(2)")
我使用了不同的CSS选择器,但它仍然选择相同的元素。

我不确定
BeautifulSoup
,但在QHarr的回答中,日期选择器将返回其他值,而不是selenium的预期值。

感谢这里的帮助。您能解释一下这段代码是如何工作的吗?仍然不理解selenium中的此方法。time=soup、 选择一个('img+div+div')。文本地点=汤。选择一个('[class^=eventInfoContainer-]:第n个类型(3)div>div')。text@DiamondJoe12根据您的问题更新答案。
driver.find_elements_by_css_selector('div[class^=eventInfoContainer-]')
time = soup.select_one('img + div + div').text 
venue = soup.select_one('[class^=eventInfoContainer-]:nth-of-type(3) div > div').tex
date = driver.find_element_by_css_selector("img[class^='eventInfoContainer-'][src$='clock.svg'] + div")
time = driver.find_element_by_css_selector("img[class^='eventInfoContainer-'] + div + div")
venue = driver.find_element_by_css_selector("img[class^='eventInfoContainer-'][src$='pin.svg'] + div > div")
address = driver.find_element_by_css_selector("img[class^='eventInfoContainer-'][src$='pin.svg'] + div > div:nth-of-type(2)")