我正在尝试使用Beautiful Soup从booking.com获取一些酒店信息。我需要从西班牙的所有住宿中获取某些信息。这是搜索网址:
当我使用开发人员工具检查结果页面中的住宿时,它说这是要搜索的标记:
<a class="hotel_name_link url" href=" /hotel/es/aran-la-abuela.html?label=gen173nr-1DCAEoggJCAlhYSDNYBGigAYgBAZgBMbgBB8gBDNgBA-gBAfgBApICAXmoAgM;sid=1677838e3fc7c26577ea908d40ad5faf;ucfs=1;srpvid=b4980e34f6e50017;srepoch=1514167274;room1=A%2CA;hpos=1;hapos=1;dest_type=country;dest_id=197;srfid=198499756e07f93263596e1640823813c2ee4fe1X1;from=searchresults ;highlight_room=#hotelTmpl" target="_blank" rel="noopener">
<span class="sr-hotel__name
" data-et-click="
customGoal:YPNdKNKNKZJUESUPTOdJDUFYQC:1
">
Hotel Spa Aran La Abuela
</span>
<span class="invisible_spoken">Opens in new window</span>
</a>
这是我的Python代码:
def init_BeautifulSoup():
global page, soup
page= requests.get("https://www.booking.com/searchresults.html?aid=304142&label=gen173nr-1DCAEoggJCAlhYSDNYBGigAYgBAZgBMbgBB8gBDNgBA-gBAfgBApICAXmoAgM&sid=1677838e3fc7c26577ea908d40ad5faf&class_interval=1&dest_id=197&dest_type=country&dtdisc=0&from_sf=1&group_adults=2&group_children=0&inac=0&index_postcard=0&label_click=undef&no_rooms=1&oos_flag=0&postcard=0&raw_dest_type=country&room1=A%2CA&sb_price_type=total&search_selected=1&src_elem=sb&ss=Spain&ss_all=0&ss_raw=spain&ssb=empty&sshis=0&order=popularity")
soup = BeautifulSoup(page.content, 'html.parser')
def get_spain_accomodations():
global accomodations
accomodations = soup.find_all(class_="hotel_name_link.url")
但是当我运行代码并打印住宿变量时,它会输出一对括号([])。然后我打印了汤对象,我意识到解析的HTML与我在Chrome中的开发人员工具中看到的非常不同,这就是为什么汤对象无法找到类“hotel_name_link.url”
发生了什么事?
答案 0 :(得分:2)
JavaScript正在加载后修改页面。因此,当您使用page.content
时,它会在JavaScript修改页面之前为您提供页面的HTML内容。我不认为您可以直接使用requests
模块来使用JavaScript抓取页面。
看看this问题。
如果您决定使用Selenium处理此问题,请检查this问题。页面加载后,您可以使用driver.page_souce
在JavaScript修改后获取页面源并将其传递给BeautifulSoup。
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
def get_page(url):
driver = webdriver.Chrome()
driver.get(url)
try:
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.TAG_NAME, 'h1')))
except TimeoutException:
print('Page timed out.')
return None
page = driver.page_source
return page
def init_BeautifulSoup():
global page, soup
page = get_page('your-url')
# handle the case where page may be None
soup = BeautifulSoup(page, 'html.parser')
不是快速或简单的解决方案,而是完成工作。
编辑:
你需要在这里改变一件事。
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.TAG_NAME, 'h1')))
部分的作用是让驱动程序明确等待,直到该元素位于我们指定的网页上,或者在您指定的延迟时间之后抛出TimeoutException
(我是用了10秒)。
我刚给你提供了一个例子。您需要在执行JavaScript之前找到加载页面上不存在的元素,并在此处替换它:(By.TAG_NAME, 'h1')
您可以通过在加载页面后检查元素并在页面源的HTML代码中检查元素是否存在来执行此操作。
您可以根据您的要求使用以下任何内容代替By.TAG_NAME
:
我建议使用id或任何名称选择器而不是css或xpath,因为它们有点慢。 ID
效果最快,而XPATH
效果最慢。