HTMLunit не может выполнить скрипт onclick mojarra в href

В настоящее время я пишу веб-скребок на основе HTMLunit для сбора названий и деталей конкретных компаний с веб-сайта выставки-ярмарки Hannovermesse. Я, кажется, столкнулся с Showtopper для моих усилий, так как я не могу заставить кнопку вперед страницы на странице результатов поиска работать.

Сайт въезда
www.hannovermesse.de/en/exhibition/exhibitors-products/advanced-search/
Затем несколько фильтров поиска устанавливаются в флажках (Регион ЕС, Промышленная автоматизация / Робототехника).

После отправки формы и загрузки результатов поиска я получаю около 400 обращений. Когда я выбираю вкладку "Участники", я получаю первую страницу результатов. Результаты поиска отображаются на
//www.hannovermesse.de/en/exhibition/exhibitors-products/search
ПРИМЕЧАНИЕ. Вам нужно выполнить всю последовательность, чтобы перейти к экрану результатов! Кажется, он использует данные сеанса /cookie, чтобы определить, что отображать, и по умолчанию он ничего не отображает.

Это дает мне 20 просмотров на первой странице и отображает внизу селектор страниц, с выбранной страницей 1.
"[<] [1] 2... | n [>]"
Чтобы собрать все контакты, мне нужно нажать на все экраны, указанные в результатах поиска.

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

Результатом всегда является ошибка во время выполнения и прерывание.

Сообщения журнала:

Май 01, 2016 18:05:11 com.gargoylesoftware.htmlunit.html.HtmlScript isExecutionNeeded ПРЕДУПРЕЖДЕНИЕ. Скрипт не является JavaScript (тип: text/html, language:). Пропуск исполнения.
Май 01, 2016 18:05:12 com.gargoylesoftware.htmlunit.javascript.StrictErrorReporter runtimeError SEVERE: runtimeError: message=[Указан недопустимый или недопустимый селектор (ошибка селектора: '*,:x': ошибка недопустимого селектора:: x).] sourceName = [ http://www.hannovermesse.de/files/001-fs5/media/layout/js/dmag.min.js%5D line=[2] lineSource=[null] lineOffset=[0]
Май 01, 2016 18:05:12 com.gargoylesoftware.htmlunit.javascript.StrictErrorReporter runtimeError SEVERE: runtimeError: message=[Указан недопустимый или недопустимый селектор (селектор: '[id='sizzle-1462118712173']: выбранный' ошибка: неверный селектор: [id="sizzle-1462118712173"]: выбрано).] sourceName = [ http://www.hannovermesse.de/files/001-fs5/media/layout/js/dmag.min.js%5D line=[2] lineSource=[null] lineOffset=[0]
Май 1, 2016 18:05:12 com.gargoylesoftware.htmlunit.IncorrectnessListenerImpl notify ПРЕДУПРЕЖДЕНИЕ: Обнаружен устаревший тип содержимого: 'text / javascript'.
Май 01, 2016 18:05:17 com.gargoylesoftware.htmlunit.IncorrectnessListenerImpl notify ВНИМАНИЕ: Обнаружен устаревший тип содержимого: application/x-javascript.

Пробовал различные настройки браузера, но не радость. Я обнаружил, что этот "недопустимый или недопустимый селектор был указан (селектор: '*,:x' ошибка: недопустимый селектор::x)."- ошибка иногда возникала в arachnid и других тестовых браузерах. Там "webClient(). WaitForBackgroundJavaScriptStartingBefore(5000);""исправил проблему. Я пробовал это, но у меня это не сработало.

Я прилагаю мою быструю и грязную пробную Java-программу для вашей справки. Я использую Eclipse MARS с библиотеками Java JRE 1.8, JUnit4 и HTMLunit 2.22

Кто-нибудь имеет представление о том, что происходит, или что нужно изменить, чтобы заставить его работать? Я не могу поверить, что я первый, кто наткнулся на это!

Мой код Java:

/*---------------------------------------------------------------------------------*/
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebClientOptions;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.html.HtmlCheckBoxInput;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlOption;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlSelect;
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;

public class App {
    static WebClient webClient;

    static String[] countries = {
                "European Union"
                                    };

    static String[] categories = {
                "Robotics"          
    };

    @SuppressWarnings("deprecation")
    public static void main(String[] args) throws Exception {

        setUp();

        HtmlPage currentPage = webClient.getPage("http://www.hannovermesse.de/en/exhibition/exhibitors-products/advanced-search/");
        System.out.println(currentPage.getTitleText()+"Web page open\n------------------------------------------------------------------\n");

        registerCountries(currentPage);
        registerCategories(currentPage);
        System.out.println("Search filters registered\n------------------------------------------------------------------\n");

        currentPage = submitSearchRequest(currentPage);
        System.out.println("Search filters submitted and results loaded\n------------------------------------------------------------------\n");

        selectExhibitorView(currentPage);
        System.out.println("Exhibitor View selected\n------------------------------------------------------------------\n");

        showCriteria(currentPage);

        showResultsCount(currentPage);

        HtmlPage backupPage = currentPage;

        for(int n=0, tn=0; n<1; n++){
            System.out.println("========================================================================================");
            System.out.println(" Results page "+n+1);

            HtmlAnchor nextPageButton = (HtmlAnchor) currentPage.getFirstByXPath(".//div[@class=\"col s-col12 m-col12 l-col12\"]/ul/following-sibling::a");
            String classValue = nextPageButton.getAttribute("class");
            nextPageButton.setAttribute("name", nextPageButton.getAttribute("class").trim());

            NamedNodeMap attribList = nextPageButton.getAttributes();
            for (int i=0; i < attribList.getLength(); i++) {
                Node node = attribList.item(i);
                String key=node.getLocalName();
                String val=node.getNodeValue();             
                System.out.printf("[%-15s] : '%s'\n", key, val);
            }

            List <HtmlElement> elementList = (List<HtmlElement>)currentPage.getByXPath(".//h4[@itemprop=\"name\"]/text()");         
            int i=0;
            for(; i<elementList.size();i++){
                System.out.printf("[%3d] '%s'\n", +(tn+i), elementList.get(i));
            }
            tn=i;

            System.out.println("Next Button :");
            final HtmlAnchor newPageLink  = (HtmlAnchor) currentPage.getAnchorByName(classValue.trim());
            currentPage = (HtmlPage) newPageLink.click();
            currentPage = nextPageButton.click();
            System.out.println("===========>[13]");

        }
        currentPage = backupPage;          

        System.out.println("Done");
        webClient.close();
    }

    private static void showResultsCount(HtmlPage currentPage) {
        String results = "";
        int count;
        results = (String) currentPage.getByXPath("String("+".//div[@class=\"col l-col8 m-col7 s-col12\"]/p[@class=\"query-text\"]/text()"+")").get(0);
        publish("Raw results : "+results);
        count= Integer.parseInt(results.split(" ")[0]);
        publish("Results : "+count+" found.\n");
    }

    private static void selectExhibitorView(HtmlPage currentPage) {
        HtmlSelect select = (HtmlSelect) currentPage.getElementById("searchResult:resultType");
        HtmlOption option = select.getOptionByValue("1");
        select.setSelectedAttribute(option, true);      
    }

    private static HtmlPage submitSearchRequest(HtmlPage currentPage) {
        try {       
            final HtmlForm form  = (HtmlForm) currentPage.getFormByName("searchAP:search");
            final HtmlSubmitInput button = form.getInputByName("searchAP:searchButton2");           
            currentPage = (HtmlPage) button.click();
            System.out.println(currentPage.getTitleText());
        } catch (Exception e) {
            System.out.println("===> Cannot submit Search Form, no submit button found!");
        }
        return currentPage; 
    }

    private static void showCriteria(HtmlPage currentPage) {
        publish("Filtercriteria for this search:");
        String results = "";
        results = (String) currentPage.getByXPath("String(.//h1[contains(text(), \"Search Result\")]/following-sibling::p)").get(0);

        String[] criteria= results.split(",");
        String key = "";
        Map<String, ArrayList<String>> cMap = new LinkedHashMap<String, ArrayList<String>>();
        ArrayList<String> value = new ArrayList<String>();
        cMap.put(key, value);

        for(int i=0; i<criteria.length; i++){
            if(criteria[i].contains(":")){
                String workCopy = new String(criteria[i]);
                String[] bits= workCopy.split(":");
                key = bits[0].trim();
                criteria[i]=bits[1].trim();
                value = new ArrayList<String>();
                cMap.put(key, value);
            }
            value.add(criteria[i].trim());
        }  

        for (Map.Entry<String, ArrayList<String>> entry : cMap.entrySet()) {
            key = entry.getKey();
            value = entry.getValue();
            if(!value.isEmpty()){
                System.out.println(key+": ");
                for (int i = 0; i < value.size(); i++) {
                    System.out.println("  "+value.get(i));
                }
            }
        }
    }

    public static void publish(String text) {
        System.out.println(text);       
    }
    public static void registerCountries(HtmlPage currentPage) {
        for(int i=0;i < countries.length; i++){
            setCountryCheckbox(currentPage, countries[i]);
        }
    }

    public static void registerCategories(HtmlPage currentPage) {
        for(int i=0;i < categories.length; i++){
            setCategoryCheckbox(currentPage, categories[i]);
        }       
    }

    public static void setCountryCheckbox(HtmlPage currentPage, String text) {
        String label="";
        HtmlCheckBoxInput input;

        try {
            label = (String) currentPage.getByXPath("String(.//label[contains(text(), \""+text+"\")]/@for)").get(0);
            System.out.print(text);
            input = currentPage.getHtmlElementById(label);
            input.setChecked(true);
            System.out.println(": "+(input.isChecked()?"SET":""));
        } catch (Exception e) {
            System.out.println("\rError: Label ID for '"+text+"' not found. ");
        }
    }

    public static void setCategoryCheckbox(HtmlPage currentPage, String text) {
        String label="";
        HtmlCheckBoxInput input;
        String XPathXpression = ".//strong[contains(text(), \""+text+"\")]/parent::div/input/@id";

        try {
            label = (String) currentPage.getByXPath("String("+XPathXpression+")").get(0);
            System.out.print(text+" : "+"'"+label+"' ");
            input = currentPage.getHtmlElementById(label);
            input.setChecked(true);
            System.out.println(": "+(input.isChecked()?"SET":""));
        } catch (Exception e) {
            System.out.println("\rError: Label ID for '"+text+"' not found. ");
        }
    }

    public static void setUp() throws InterruptedException {
          webClient = new WebClient(BrowserVersion.FIREFOX_45);
          WebClientOptions options = webClient.getOptions();
          options.setPrintContentOnFailingStatusCode(true);
          options.setJavaScriptEnabled(true);
          options.setThrowExceptionOnScriptError(false);
          options.setThrowExceptionOnFailingStatusCode(false);
          webClient.waitForBackgroundJavaScriptStartingBefore(5000);          
      }
}

2 ответа

Всего две подсказки:

  1. Указан неверный или недопустимый селектор.... это действительно распространенный вывод при тестировании веб-приложений с использованием jQuery с HtmlUnit. Это означает, что jQuery выполняет некоторые вызовы для проверки возможностей селектора css, поддерживаемого браузером. Поскольку HtmlUnit регистрирует исключения в момент конструирования, вы увидите этот вывод журнала. Исключения обрабатываются из (jQuery) Java-кода позже. Обычно вы можете просто игнорировать это.

  2. webClient.waitForBackgroundJavaScriptStartingBefore (5000); это не своего рода вариант. Этот вызов НЕ устанавливает время ожидания. Вы должны поместить этот вызов в ваш обычный поток приложений, обычно после запуска некоторых действий. Это может потребоваться, если вы запускаете действия Ajax.

Если вы используете HtmlSubmitInput для кнопки, HTMLUnit попытается найти поле типа ввода вместо поиска Button.

Используйте HtmlButton вместо HtmlSubmitInput

Вот пример.

HtmlButton button = form.getButtonByName ("submitButton");

Другие вопросы по тегам