我正在抓取网页的前端,难以在div中获取div的HMTL文本。
基本上,我是在模拟点击-页面上列出的每个事件一次。在这里,我要抓取事件的日期和时间以及事件的位置。
以下是我要抓取的其中一个页面的示例:
<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 links
event_list = driver.find_elements_by_css_selector('div[class^=eventList-] a[class^=event-]')
# collect href attribute of events in even_list
events.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, 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-9e539994”中的第二个元素(在img之后)。父div“ eventInfoContainer-9e539994”位于位置[1],它同样是其父div“ eventInfoContainer-54d5deb3”中的第二个元素(在“ lineupContainer”之后)。
按照这种逻辑,我不应该通过以下代码访问日期文本:(访问容器(第0个位置元素)内的第1个位置元素,其父元素为第1个位置元素吗?>
for event in events:
driver.get(event)
uniqueEventContainer = driver.find_elements_by_css_selector('div[class^=eventInfoContainer-]')[0][1][1]
我收到以下错误:
TypeError: 'WebElement' object does not support indexing
任何帮助表示赞赏!预先谢谢你。
答案 0 :(得分:2)
当您索引到webElements列表(find_elements_by_css_selector('div[class^=eventInfoContainer-]')
返回的内容)时,您将获得一个webElement,您将无法进一步对其进行索引。您可以拆分webElement的文本以生成列表以供进一步索引。
如果页面之间有规则的结构,则可以将div的html加载到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)
答案 1 :(得分:1)
如错误所示,webelements没有索引。您感到困惑的是列表。
这里
driver.find_elements_by_css_selector('div[class^=eventInfoContainer-]')
此代码返回网络元素列表。这就是为什么您可以使用列表的索引访问Webelement的原因。但是该元素没有索引到另一个Web元素。您没有列表列表。
这就是为什么
driver.find_elements_by_css_selector('div[class^=eventInfoContainer-]')[0]
有效。但是driver.find_elements_by_css_selector('div[class^=eventInfoContainer-][0][1]')
不会。
编辑 :(评论中的问题的答案)
这不是硒代码。
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
标签,然后再次找到前一个div
标签的同级dev标签。
在第二行中,它找到具有以eventInfoContainer-
开头的类的第三个同级标记,然后找到子项div
并找到该div
的子项。
这可以直接使用硒来完成:
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的回答中,日期选择器将返回其他值而不是硒的预期值。