Я пытаюсь извлечь обзоры внутри i-frame, используя селен в python, но не могу получить доступ к внутреннему HTML.? - PullRequest
0 голосов
/ 08 мая 2020

Я пытаюсь извлечь отзывы из iframe, и я пытаюсь переключиться на iframe, и, думаю, я успешно переключился, но не могу получить доступ к другим тегам и атрибутам ..

Я пробовал несколько Решение, которое является комментарием, мне нужно получить конкретный c div для просмотра или даже если мы получим полный источник страницы iframe, тогда я смогу выполнить синтаксический анализ через Beautifulsoup.

Url = https://www.aliexpress.com/item/4000295971597.html?spm=a2g0o.productlist.0.0.46754f9bCFP2xJ&s=p&ad_pvid=202005070358123970448424509400000207120_1&algo_pvid=28913e75-ad10-4d7c-a25b-e1c67d3e18be&algo_expid=28913e75-ad10-4d7c-a25b-e1c67d3e18be-0&btsid=0ab6d69f15888490922438266e45ea&ws_ab_test=searchweb0_0, searchweb201602_, searchweb201603_

Мой код:

from telnetlib import EC
from time import sleep
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

def get_pro_reviews():
driver = webdriver.Chrome()
driver.get(web_url)
try:
    driver.execute_script("window.scrollTo(0, 200)")
    driver.implicitly_wait(10)
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable(
        (By.XPATH, '/html/body/div[5]/div/div[3]/div[2]/div[2]/div[1]/div/div[1]/ul/li[2]'))).click()
    print('==> Review tab Clicked')
    driver.implicitly_wait(5)
    driver.execute_script("window.scrollTo(200, 1200)")
    sleep(5)
except Exception as error:
    product['Review'] = 'Reviews Not available'
    print(f'Error in Clicking review tab ==>{error}')
try:
    sleep(5)
    # driver.switch_to.frame(driver.find_element_by_tag_name("iframe"))
    # iframes=driver.find_elements_by_tag_name("iframe")
    # chn=driver.switch_to.frame(iframes[0])
    print(driver)
    che = WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(
        driver.find_element_by_xpath("//*[@id='product-evaluation']")))
    print('==> Swithched to iframe')
    print(che)
    print(driver)
    review_elem = driver.page_source()
    # review_elem = driver.find_element_by_css_selector('div.feedback-list-wrap')
    print(review_elem)
    # review_elem = chn.find_element_by_xpath('/html/body/div/div[5]')
    review_elem_source_code = review_elem.get_attribute("innerHTML")
    review_elem_soup: BeautifulSoup = BeautifulSoup(review_elem_source_code, 'html.parser')
    print(review_elem_soup)

    for review_raw in review_elem_soup.find_elements_by_css_selector('div.feedback-item'):
        print(review_raw)
    driver.switch_to.default_content()
except Exception as error:
    print(f'Error in getting Reviews ==>{error}')

Ошибка:

Error in getting Reviews ==>'str' object is not callable

Это те обзоры, которые мне нужны!

enter image description here

1 Ответ

1 голос
/ 08 мая 2020

Я добавил web_url переменную вверху, потому что она не была определена.

Я добавил product как dict вверху, потому что был не определено. Я предполагаю, что это диктат, потому что вы делаете product['Review'] = 'Reviews Not available'. Если он у вас определен в другом месте, удалите оба.

Теперь мы рассмотрим ваши ошибки:

review_elem = driver.page_source() 

Ошибки:

1) page_source - это свойство, а не метод класса, поэтому вам следует удалить ()

2) Это вернет строку, содержащую все html, поэтому вы получите ошибку:

"Error in getting Reviews ==>'str' object is not callable"

str, потому что review_elem в данный момент является строкой и не вызывается, потому что вы не можете вызвать свойство (()), вы просто получаете к нему доступ как атрибут класса.

После понимания этой концепции это не будет работать для вас. Если вы продолжите и запустите код в том виде, в каком он у вас есть, вы получите еще одну ошибку при назначении этого:

review_elem_source_code = review_elem.get_attribute("innerHTML")

, потому что review_elem (который является строкой) не имеет метода get_attribute(). Итак, я предлагаю следующее:

review_elem_source_code = driver.execute_script("return document.body.innerHTML;")

Это получит внутренний Html iframe.

Наконец, после этого вы получите еще одну ошибку из-за следующей ошибки в для l oop:

review_elem_soup.find_elements_by_css_selector('div.feedback-item')

find_elements_by_css_selector() не существует в BeautifulSoup, это существует в драйвере. Итак, чтобы получить все элементы, которые вы хотите с BeautifulSoup, вы должны изменить на это:

review_elem_soup.select('div.feedback-item')

Вот код:

from time import sleep
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

web_url = "https://www.aliexpress.com/item/4000295971597.html?spm=a2g0o.productlist.0.0.46754f9bCFP2xJ&s=p&ad_pvid=202005070358123970448424509400000207120_1&algo_pvid=28913e75-ad10-4d7c-a25b-e1c67d3e18be&algo_expid=28913e75-ad10-4d7c-a25b-e1c67d3e18be-0&btsid=0ab6d69f15888490922438266e45ea&ws_ab_test=searchweb0_0,searchweb201602_,searchweb201603_"
driver = webdriver.Chrome()
driver.get(web_url)
product = {}
try:
    driver.execute_script("window.scrollTo(0, 200)")
    driver.implicitly_wait(10)
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable(
        (By.XPATH, '/html/body/div[5]/div/div[3]/div[2]/div[2]/div[1]/div/div[1]/ul/li[2]'))).click()
    print('==> Review tab Clicked')
    driver.implicitly_wait(5)
    driver.execute_script("window.scrollTo(200, 1200)")
    sleep(5)
except Exception as error:
    product['Review'] = 'Reviews Not available'
    print(f'Error in Clicking review tab ==>{error}')
try:
    sleep(5)
    che = WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(
        driver.find_element_by_xpath("//*[@id='product-evaluation']")))
    print('==> Switched to iframe')
    review_elem_source_code = driver.execute_script("return document.body.innerHTML;")
    review_elem_soup: BeautifulSoup = BeautifulSoup(review_elem_source_code, 'html.parser')
    for review_raw in review_elem_soup.select('div.feedback-item'):
        print(review_raw)
    driver.switch_to.default_content()
except Exception as error:
    print(f'Error in getting Reviews ==>{error}')

Ps: Я удаляю большинство ваших отпечатков поэтому код легче объяснить.

Надеюсь, это поможет вам достичь желаемого.

...