为了账号安全,请及时绑定邮箱和手机立即绑定

使用 Selenium 在 div 中查找索引元素

使用 Selenium 在 div 中查找索引元素

Go
慕神8447489 2022-01-18 13:38:47
我正在抓取网页的前端,并且难以在 div 中获取 div 的 HMTL 文本。基本上,我正在模拟点击——页面上列出的每个事件都有一个。从那里,我想抓取事件的日期和时间,以及事件的位置。这是我试图抓取的页面之一的示例: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<div class="eventInfoContainer-54d5deb3">    <div class="lineupContainer-570750d2">     <div class="eventInfoContainer-9e539994">        <img src="assets.bandsintown.com/images.clock.svg">        <div>Sunday, April 21st, 2019</div> <!––***––>         <div class="eventInfoContainer-50768f6d">5:00PM</div><!––***––>      </div> <div class="eventInfoContainer-1a68a0e1">    <img src="assets.bandsintown.com/images.clock.svg">    <div class="eventInfoContainer-2d9f07df">        <div>Aura Nightclub</div> <!––***––>         <div>283 1st St., San Jose, CA 95113</div> <!––***––> </div>我已经用星号标记了我想要提取的元素——日期、时间、地点和地址。这是我的代码:base_url = 'https://www.bandsintown.com/?came_from=257&page='events = []eventContainerBucket = []for i in range(1, 2):    driver.get(base_url + str(i))# get events linksevent_list = driver.find_elements_by_css_selector('div[class^=eventList-] a[class^=event-]')# collect href attribute of events in even_listevents.extend(list(event.get_attribute("href") for event in event_list))# iterate through all events and open them.for event in events:    driver.get(event)    uniqueEventContainer = driver.find_elements_by_css_selector('div[class^=eventInfoContainer-]')[0]       print "Event information: "+ uniqueEventContainer.text这打印:Event information: Sunday, April 21st, 20193:00 PMSan Francisco Brewing Co.3150 Polk St, Sf, CA 94109View All The Fourth Son Tour Dates我的问题是我无法单独访问嵌套的 eventInfoContainer div。例如,“日期”div 是位置 [1],因为它是其父 div“eventInfoContainer-9e539994”中的第二个元素(在 img 之后)。父 div“eventInfoContainer-9e539994”位于位置 [1] 中,它同样是其父 div“eventInfoContainer-54d5deb3”中的第二个元素(在“lineupContainer”之后)。按照这个逻辑,我不应该能够通过这段代码访问日期文本吗:(访问第一个位置元素,它的父元素是容器内的第一个位置元素(第 0 个位置元素)?
查看完整描述

2 回答

?
冉冉说

TA贡献1877条经验 获得超1个赞

当您索引到 webElements 列表(这是find_elements_by_css_selector('div[class^=eventInfoContainer-]')返回的)时,您会得到一个 webElement,您不能进一步索引它。您可以拆分 webElement 的文本以生成列表以供进一步索引。


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


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)


查看完整回答
反对 回复 2022-01-18
?
叮当猫咪

TA贡献1776条经验 获得超12个赞

正如错误所示,webelements 没有索引。您感到困惑的是列表。


这里


driver.find_elements_by_css_selector('div[class^=eventInfoContainer-]')

此代码返回 web 元素列表。这就是为什么您可以使用列表的索引访问 web 元素的原因。但是该元素没有对另一个 web 元素的索引。您没有得到列表列表。


这就是为什么 driver.find_elements_by_css_selector('div[class^=eventInfoContainer-]')[0]有效。但driver.find_elements_by_css_selector('div[class^=eventInfoContainer-][0][1]')没有。


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


它不是 slenium 代码。


QHarr在答案中发布的代码使用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标签,然后再次找到前一个标签的兄弟 devdiv标签。在第二行中,它找到了 class 开头的第三个兄弟标签,eventInfoContainer-然后它找到了 childdiv并找到了 that 的 child div。


查看CSS 选择器


这可以直接使用 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 的回答中,日期选择器将返回其他值而不是硒的预期值。


查看完整回答
反对 回复 2022-01-18
  • 2 回答
  • 0 关注
  • 488 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信