动态内容的网络抓取

希望能帮助我从以下链接中抓取结果: sample link

我正在使用Python 3.7,BeautifulSoup 4和Selenium。

我已经编写了一个程序来提取酒店用户评论的功能,例如评论者姓名,评论日期,评论者得分,评论者所在国家/地区,住宿日期,评论标题以及评论本身(在这种情况下,评论是分开的分为正面和负面部分)。 我使用BeautifulSoup 4从HTML标签中提取文本,依靠Selenium单击“ cookie通知”按钮以及循环浏览页面结果。

虽然我成功地浏览了页面结果,但我没有提取从第一页开始的所有内容。每N个页面从第一个结果页面检索相同的内容,我敢打赌这可能是因为内容是通过JQuery加载的。在这一点上,我不确定行为是什么,或者我需要在页面源代码中寻找什么,或者如何找到解决方案。

任何提示或建议将不胜感激!

我的代码的原始代码段:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait,Select
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
import time

driver = webdriver.Chrome('/Users/admin/Desktop/chrome_driver/chromedriver')

#initiate driver-browser via Selenium - with original url
driver.get('link1')

def acceptCookies():
    time.sleep(3)
    element = driver.find_elements_by_xpath("//button[@class='cookie-warning-v2__banner-cta bui-button bui-button--wide bui-button--secondary close_warning']")
    if element != None:
        element = driver.find_elements_by_xpath("//button[@class='cookie-warning-v2__banner-cta bui-button bui-button--wide bui-button--secondary close_warning']")
        element[0].click()

def getData(count,soup):
    try:
        for line in soup.find_all('li',class_='review_item'): 
            count += 1
            review={}
            review["review_metadata"]={}
            review["review_metadata"]["review_date"] = line.find('p',class_='review_item_date').text.strip()
            if line.find('p',class_='review_staydate') != None:
                review["review_metadata"]["review_staydate"] = line.find('p',class_='review_staydate').text.strip()
            review["review_metadata"]["reviewer_name"] = line.find('p',class_='reviewer_name').text.strip()
            print(review["review_metadata"]["reviewer_name"])
            review["review_metadata"]["reviewer_country"] = line.find('span',class_='reviewer_country').text.strip()
            review["review_metadata"]["reviewer_score"] = line.find('span',class_='review-score-badge').text.strip()
            if line.find('p',class_='review_pos') != None:
                review["review_metadata"]["review_pos"] = line.find('p',class_='review_pos').text.strip()
            if line.find('p',class_='review_neg') != None:
                review["review_metadata"]["review_neg"] = line.find('p',class_='review_neg').text.strip()
            scoreword = line.find('span',class_='review_item_header_scoreword')
            if scoreword != None :
                review["review_metadata"]["review_header"] = scoreword.text.strip()
            else:
                review["review_metadata"]["review_header"] = ""  
            hotel_reviews[count] = review
        return hotel_reviews
    except Exception as e:
        return print('the error is',e)

# Finds max-range of pagination (number of result pages retrieved)
def find_max_pages():
    max_pages = driver.find_elements_by_xpath("//div[@class='bui-pagination__list']//div//span")
    max_pages = max_pages[-1].text
    max_pages = max_pages.split()
    max_pages = int(max_pages[1])

    return max_pages


hotel_reviews= {}

count = 0
review_page = {}
hotel_reviews_2 = []

# accept on Cookie-Notification
acceptCookies()
# Find Max Pages
max_pages = find_max_pages()
# Find every pagination link in order to loop through each review page carousel
element = driver.find_elements_by_xpath("//a[@class='bui-pagination__link']")
for item in range(max_pages-1):
    review_page = getData(count,soup)
    hotel_reviews_2.extend(review_page)
    time.sleep(2)
    element = driver.find_elements_by_xpath("//a[@class='bui-pagination__link']")
    element[item].click()
    driver.get(url=driver.current_url)
    print(driver.page_source)
    print(driver.current_url)
    soup = BeautifulSoup(driver.page_source,'lxml')
a85935935 回答:动态内容的网络抓取

编辑:问题不在于等待元素加载。该网页根本没有类别review_item的任何其他元素。 getData()方法需要更新,以从属于review_list_new_item_block类的适当元素中提取信息。

旧答案:

我认为,一旦单击以打开新的结果页面,该页面上的某些元素将被删除,而另一些元素将被添加。您可以使用WebDriverWait等到特定元素过时:

wait = WebDriverWait(driver,20);
wait.until(EC.staleness_of(element_of_interest));

如果这不适用,则可能是另一个条件。检查所有预定义的conditions可能很有用。

本文链接:https://www.f2er.com/3110264.html

大家都在问