Python 使用selenium查找div中的索引元素
我正在抓取一个网页的前端,很难在一个div中获取div的HMTL文本 基本上,我是在模拟点击——页面上列出的每个事件一次。从那里,我想抓取事件的日期和时间,以及事件的地点 下面是一个我正在努力抓取的页面示例: 这张照片是: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
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)")