Python3 Selenium Issue - PullRequest
       1

Python3 Selenium Issue

1 голос
/ 15 марта 2019

Я хочу просмотреть некоторые комментарии через Веб-страницу . Когда я пытаюсь выбрать кнопку перехода (перейти на следующую страницу) с помощью Selenium, она всегда показывает всплывающее окно. Я пытался закрыть всплывающее окно с помощью Selenium, но оно все равно не работает. Может ли кто-нибудь помочь мне исправить эту проблему и помочь мне выполнить функцию next_page () ниже ? Большое спасибо!

Я уже выполнил функцию scrap_comments () . Что я хочу сделать, это завершить функцию next_page () .

Вот мой код.

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():
    """
    It is a function to execute Next Page function
    """
    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
    WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="cPageBtn"]')))
    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)

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

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

    browser.close()

Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 16 марта 2019

ОК, так что действительно должно было быть какое-то окно, в которое нужно переключиться, чтобы Selenium щелкнул по элементу '//*[@id="appd_wrap_close"]', и я некоторое время пытался найти его.В конце концов я думаю, что наткнулся на то, что мешает вам нажать на этот элемент.У них есть программное обеспечение для отслеживания испытаний.Вот как я это выяснил: сначала все, что я сделал, было очевидным, осмотрите элемент «x», на который вы пытались нажать.Я попытался найти что-то необычное в этом элементе, и через некоторое время я заметил, что к нему прикреплен Event.Я нажимаю на Event в инспекторе Firefox и вижу следующее:

'//*[@id=

хмм ... Я ожидал, что он просто закроет окно, этоно у него есть следующий JavaScript:

function() {
  c.setCookie({
    manualclose: "1"
  }, "", 1), u.collapse(), window.__bfi.push(["_tracklog", "pcfloatClose", location.href + "&urlPageId=" + e + "&htmlType=" + d])
}

Ну, есть u.collapse, который, как я догадываюсь, - это весь код, необходимый для свертывания панели.Но зачем все это?Несколько вещей показались мне странными: почему он устанавливает cookie каждый раз, когда вы нажимаете эту кнопку?И почему это называется **manual**close?Затем я посмотрел немного поближе и увидел текст, следующий за «щелчком»: _esUnionOnline/R3/float/floating_normal.min.js?20190316:2.ГектометрТаким образом, они вызывают файл JavaScript.И это выглядит как URL.Почему они идут на все эти неприятности из-за события щелчка мышью на этом маленьком 'x'?

Я намыкаю на него и, конечно же, он показывает мне https://webresource.c-ctrip.com/ResUnionOnline/R3/float/floating_normal.min.js?20190306:2.

Я перехожу кэтот сайт и найти большой файл, содержащий минимизированный JavascriptЯ поставил его через не минификатор (я использовал https://unminify.com/). прямо в верхней части документа, я вижу

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

ab_testing_tracker ..... это не звучит хорошо.Поэтому я провожу поиск по этому вопросу и нахожу несколько скрытых входных данных с идентификатором ab_testing_tracker. На данный момент я совершенно уверен, что они обнаруживают селен и не позволяют вам щелкнуть по нему. После небольшого поиска в общих тестовых методах отслеживанияи обнаружил, что, среди прочего, проверка userAgent была обычным делом. Пользовательский агент Selenium по умолчанию - это просто веб-драйвер, так как вы можете прочитать здесь , поэтому я выполнил поиск. Конечно, есть 20 результатов.все в форме navigator.userAgent, а некоторые выглядят как

i.test(navigator.userAgent)

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

function n() {
    var t, n;
    switch (n = e.ResponseStatus.Errors[0].ErrorCode ? e.ResponseStatus.Errors[0].ErrorCode : "") {
        case "104":
            t = "验证码输入超时";
            break;
        case "105":
            t = "验证码输入错误";
            break;
        case "106":
            t = "手机号码不正确";
            break;
        case "107":
            t = "客户端IP不能为空";
            break;
        case "108":
            t = "短信内容不能为空";
            break;
        case "109":
            t = "同一号码,两分钟内最多发一次";
            break;
        case "110":
            t = "一天内同一手机最多发两次";
            break;
        case "111":
            t = "一天内同一IP最多发五次";
            break;
        default:
            t = "短信发送失败,请重新发送"
    }
    return t
}

в своем javascript и с помощью google translate выяснили, что последние несколько переключателей проверяют, заходили ли вы на сайт определенное количество раз.В последнее время я не мог придумать реальный способ обойти это ... по крайней мере, в Firefox.

Если вы хотите провести тестирование в Chrome, эта коробка начинает сворачиваться по умолчанию (по любой причине), так что вы не можетене нужно беспокоиться о том, чтобы избавиться от него.

Итак, если коротко, если вы можете тестировать в Chrome, вы можете просто удалить следующую строку и не беспокоиться о глупой коробке.Тестовый трекер все еще может быть, я не знаю, как он работает, и я подозреваю, что они написали его сами, так как я не могу найти инструмент, который использует эти узлы «ab_test_tracking» - на самом деле, поиск в Google по «ab_test_tracking» дает малорезультаты, и большинство из них были именно на этом сайте.

Дайте мне знать, какие у вас есть варианты (нужно ли вам использовать Firefox по какой-то причине?), и если вы сможете запустить тест в Chrome, дайте мне знатьесли это работает!

Редактировать в отношении кнопки нумерации страниц Итак, я обнаружил, что то же самое относится и к кнопке, которую вы пытаетесь нажать, чтобы перейти на следующую страницу - у нее есть событие onClickон также ссылается на огромный уменьшенный файл с тестовым отслеживанием, поэтому я думаю, что поэтому вы не можете нажать на кнопку, а селен никогда не пройдет первую страницу.

Но кнопка «Далее» не работаетесть скрипт, который он вызывает по клику.Вы должны быть в состоянии нажать эту кнопку с

browser.find_element_by_xpath('//*[@id="divCtripComment"]/div[4]/div/a[2]')

и дайте мне знать, если это работает для вас.

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

Благодаря руководству Пека я могу выполнить функцию next_page ().Однако всплывающее окно - это метод снятия отпечатков в браузере для отслеживания пользователя через Интернет.У нас нет идеи о том, как обойти технику отслеживания сейчас.Код ниже - следующая страница (), которую я завершил.

def next_page(page):
    """
    It is a function to execute Next Page function
    param: page. # Integer, it depends on what page you want to change to.
    """
    retryNum = 5

    while retryNum >= 0:
        try:
            # page is the page you see right now, what you wanna do is to change to the next page.
            page = page + 1
            # Clear
            browser.find_element_by_id("cPageNum").clear()
            # Send keys
            browser.find_element_by_id("cPageNum").send_keys(page)
            # Click goto button
            browser.find_element_by_id("cPageBtn").click()
            # Sleep for random seconds as waiting for loading
            time.sleep(random.randint(15, 25))
            # Check current page
            currentPage = int(browser.find_element_by_css_selector('a.current').text)

            if currentPage != page:
                retryNum -= 1
                print('Retry!')
                continue
            else:
                break
        except Exception as e:
            assert 'Failed to change to next page'
            return False
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...