現在、私はHTMLunitforに基づいてWebスクレイパーを作成しています Hannovermesse見本市の展示会ウェブサイトからの会社名と詳細。 検索結果ページの ページの転送ボタンを操作できないため、私は自分の努力のためにショーストッパーに出会ったようです。HTMLunitはhrefのonclick mojarraスクリプトを実行できません
エントリのウェブサイトは
www.hannovermesse.de/en/exhibition/exhibitors-products/advanced-search/
その後、いくつかの検索フィルタは、チェックボックス(EU地域、産業用オートメーション/ロボット)に設定されています。
フォームを送信して検索結果を読み込んだ後、出展者タブを選択すると 約400件のヒットが得られ、最初の結果ページが表示されます。 検索結果は に表示されます
//www.hannovermesse.de/en/exhibition/exhibitors-products/search
注:結果画面に移動するには、シーケンス全体を実行する必要があります。 セッション/ Cookieデータを使用して表示する内容を決定すると思われます。デフォルトでは、 は何も表示しません。
これは最初のページで20ヒットを表示し、ページ下部に セレクタを選択してページ1を選択して表示します。
[] [1] 2 ... | n [>] "
すべての連絡先を収集するには、検索結果に表示されているすべての画面 をクリックする必要があります。
右のボタンを使用してページを繰り返し、 右ボタンがアクティブでなくなったときにループを終了して終了するときに、各ページの会社の詳細を収集していました。 私は右ボタンにgetXPathのような様々な手段をつけて検証しました。 はName属性を追加することでそれを修正しました。私は 通常のHTMLanchor生成関数でそれを見つけることができました。
結果は常にランタイムエラーであり、中止されます。
Mai 01, 2016 6:05:11 PM com.gargoylesoftware.htmlunit.html.HtmlScript isExecutionNeeded WARNING: Script is not JavaScript (type: text/html, language:). Skipping execution.
Mai 01, 2016 6:05:12 PM com.gargoylesoftware.htmlunit.javascript.StrictErrorReporter runtimeError SEVERE: runtimeError: message=[An invalid or illegal selector was specified (selector: '*,:x' error: Invalid selector: :x).] sourceName=[ http://www.hannovermesse.de/files/001-fs5/media/layout/js/dmag.min.js] line=[2] lineSource=[null] lineOffset=[0]
Mai 01, 2016 6:05:12 PM com.gargoylesoftware.htmlunit.javascript.StrictErrorReporter runtimeError SEVERE: runtimeError: message=[An invalid or illegal selector was specified (selector: '[id='sizzle-1462118712173'] :selected' error: Invalid selector: [id="sizzle-1462118712173"] :selected).] sourceName=[ http://www.hannovermesse.de/files/001-fs5/media/layout/js/dmag.min.js] line=[2] lineSource=[null] lineOffset=[0]
Mai 01, 2016 6:05:12 PM com.gargoylesoftware.htmlunit.IncorrectnessListenerImpl notify WARNING: Obsolete content type encountered: 'text/javascript'.
Mai 01, 2016 6:05:17 PM com.gargoylesoftware.htmlunit.IncorrectnessListenerImpl notify WARNING: Obsolete content type encountered: 'application/x-javascript'.
は、様々なブラウザのオプション設定を試してみましたが、何の喜び:
ログメッセージはありません。私はこの "無効なまたは不正なセレクタが指定されていました(セレクタ: '*、:x'エラー:無効 セレクタ::x)" - クラッカーがクラックアップしている可能性があります。そこ 「Webクライアント()waitForBackgroundJavaScriptStartingBefore(5000);」」問題を修正し、私は、それは私のために働いていないことを試してみました
私は、拙速な概念実証のJavaを囲むています。あなたの参照のためのプログラム。 は、私は、Java JRE 1.8、JUnit4とHTMLunit 2.22 LIBS
とEclipseのMARSを使用しています誰もが何が起こっているか任意のアイデアを持っている、またはそれを動作させるために変更すること何?私は は、私信じることができませんこれにつまずいて最初の人です!
私の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);
}
}
この問題は、HTMLunitで使用されているMozilla Rhino Javascript Engineの奇抜なものです。 私はonclickステートメントの最後に問題の「return false」ステートメントを切り落として実行しました。しかし、ウェブサイトは私のセッションを切断し続けていたので、スクリプトはまだ商品を引き渡さなかった。私は掻爬の試みを検出したと思う。ですから、私はそれをあきらめなければなりませんでした。 – Helmut