Возможно ли для WebDriver щелкнуть элемент с событием щелчка мышью, которое вызывает файл JavaScript, который включает тестовый трекер? - PullRequest
0 голосов
/ 17 марта 2019

Это мой вопрос, который возникает из вопроса другого пользователя . Если вы посмотрите на мой ответ, вы получите некоторый контекст для этого вопроса. URL-адрес веб-страницы, на которую я собираюсь перейти: https://hotels.ctrip.com/hotel/347422.html?isFull=F#ctm_ref=hod_sr_lst_dl_n_1_8, если вы хотите проверить это сами.

Рассмотрим скрипт python selenium, найденный внизу вопроса. Ничего не происходит, когда селен пытается нажать на этот элемент:

browser.find_element_by_xpath('//*[@id="cPageBtn"]').click()

То же самое с этим элементом

browser.find_element_by_xpath('//*[@id="appd_wrap_close"]').click()

При отладке моего сценария селена для каждого элемента я подтвердил, что селен может найти элемент очень хорошо; он не скрыт внутри iFrame, отключен или любой другой странности, которую я обычно проверяю на предмет неудачных действий селена.

Однако, у него есть событие щелчка мышью, которое вызывает интересный файл JavaScript, и я действительно смог получить к нему доступ, перейдя по URL, показанному здесь:

Test Tracker

При наведении курсора на URL выяснилось, что это https://webresource.c -ctrip.com / ResUnionOnline / R3 / float / floating_normal.min.js? 20190306: 2 .

В самом начале файла я нашел

document.getElementById("ab_testing_tracker") && "abTestValue_Value" != h ? 
document.getElementById("ab_testing_tracker").value

Поэтому я ищу (с помощью селектора CSS в консоли разработчика) HTML-страницу веб-страницы для элемента с идентификатором "ab_testing_tracker", и я менее чем удивлен, что он ничего не возвращает. Затем я унифицировал и искал в файле все экземпляры "ab_testing_tracker". Это привело меня к этому элементу:

document.getElementsByTagName("body")[0].insertAdjacentHTML("afterBegin","<input type='hidden' name='ab_testing_tracker' id='ab_testing_tracker' value='"+h.split("|")[1]+"'>")

Похоже, что в body документа есть скрытый узел ввода для целей автоматического отслеживания. Поиск в Google показал, что отслеживание автоматизации часто выполняется путем просмотра свойства navigator.userAgent и поиска пользовательских агентов, которые указывают на автоматизацию. Но сценарий использует случайный легитимный userAgent каждый раз, поэтому я не думаю, что userAgent - это способ обнаружения селена.

Сводка и возможные обходные пути

Selenium не может щелкать определенные элементы на веб-странице, вероятно, из-за тестирования отслеживания веб-сайтом. Есть пара вещей, о которых я подумал, чтобы обойти это: может быть, я могу отключить события нажатия при использовании селена? Это я не знаю, как сделать, и не смог найти способ после поиска в Интернете. Затем я попытался щелкнуть по нему с помощью исполнителя Javascript, но это не сработало.

Кто-нибудь знает способ обойти тестовый трекер и щелкнуть по нужному элементу?

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By

# url
url = "https://hotels.ctrip.com/hotel/347422.html?isFull=F#ctm_ref=hod_sr_lst_dl_n_1_8"

# User Agent
User_Agent_List = ["Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.2 (KHTML, like Gecko) Chrome/22.0.1216.0 Safari/537.2",
                   "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)",
                   "Mozilla/5.0 (compatible; MSIE 10.0; Macintosh; Intel Mac OS X 10_7_3; Trident/6.0)",
                   "Opera/9.80 (X11; Linux i686; U; ru) Presto/2.8.131 Version/11.11",
                   "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.2 (KHTML, like Gecko) Chrome/22.0.1216.0 Safari/537.2",
                   "Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:16.0.1) Gecko/20121011 Firefox/16.0.1",
                   "Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25"]

# Define the related lists
Score = []
Travel_Types = []
Room_Types = []
Travel_Dates = []
Comments = []

DEFINE_PAGE = 10

def next_page():

    current_page = int(browser.find_element_by_css_selector('a.current').text)

    # First, clear the input box
    browser.find_element_by_id("cPageNum").clear()
    print('Clear the input page')

    # Second, input the next page
    nextPage = current_page + 1
    print('Next page ',nextPage)
    browser.find_element_by_id("cPageNum").send_keys(nextPage)

    # Third, press the goto button
    browser.find_element_by_xpath('//*[@id="cPageBtn"]').click()



def scrap_comments():
    """
    It is a function to scrap User comments, Score, Room types, Dates.
    """
    html = browser.page_source
    soup = BeautifulSoup(html, "lxml")
    scores_total = soup.find_all('span', attrs={"class":"n"})
    # We only want [0], [2], [4], ...
    travel_types = soup.find_all('span', attrs={"class":"type"})
    room_types = soup.find_all('a', attrs={"class":"room J_baseroom_link room_link"})
    travel_dates = soup.find_all('span', attrs={"class":"date"})
    comments = soup.find_all('div', attrs={"class":"J_commentDetail"})
    # Save score in the Score list
    for i in range(2,len(scores_total),2):
        Score.append(scores_total[i].string)
    Travel_Types.append(item.text for item in travel_types)
    Room_Types.append(item.text for item in room_types)
    Travel_Dates.append(item.text for item in travel_dates)
    Comments.append(item.text.replace('\n','') for item in comments)

if __name__ == '__main__':

    # Random choose a user-agent
    user_agent = random.choice(User_Agent_List)
    print('User-Agent: ', user_agent)

    # Browser options setting
    options = Options()
    options.add_argument(user_agent)
    options.add_argument("disable-infobars")

    # Open a Firefox browser
    browser = webdriver.Firefox(options=options)
    browser.get(url)


    browser.find_element_by_xpath('//*[@id="appd_wrap_close"]').click()

    page = 1    
    while page <= DEFINE_PAGE:
        scrap_comments()
        next_page()

    browser.close()

1 Ответ

0 голосов
/ 17 марта 2019

Проблема не в отслеживании или событии щелчка, проблема в синхронизации и, возможно, размере браузера. Разверните окно браузера и добавьте явное ожидание при поиске кнопки закрытия баннера

browser = webdriver.Firefox(options=options)
browser.maximize_window()
browser.get(url)

wait = WebDriverWait(browser, 10)

wait.until(EC.element_to_be_clickable((By.ID, 'appd_wrap_close'))).click()
wait.until(EC.invisibility_of_element_located((By.ID, 'appd_wrap_default')))

current_page = int(browser.find_element_by_css_selector('a.current').text)
next_page = current_page + 1

page_number_field = wait.until(EC.visibility_of_element_located((By.ID, 'cPageNum')))
page_number_field.clear()
page_number_field.send_keys(next_page)
wait.until(EC.element_to_be_clickable((By.ID, 'cPageBtn'))).click()
...