【问题标题】:Web scraping Google Images with Java使用 Java 抓取 Google 图片的网页
【发布时间】:2014-10-12 17:25:39
【问题描述】:

我的任务是制作一个用户用来搜索 theirQuery 的三张图片的应用程序。它可以用任何语言编写,建议使用 Python。但是,我使用 Python 的 GUI 技能很差,我最熟悉 Java,并且我已经下载了 Eclipse SWT 包,我打算使用它。

好的,到目前为止你做了什么

我拉皮条他们的示例代码,使一个简单的网络浏览器。我让它显示谷歌图片作为主页,并打算使用 JavaScript/jQuery 自动填写他们的查询,并返回前三张图片。 (我还打算以某种方式使用 JavaScript/jQuery 来返回这三张图片。)

根据 Eclipse SWT 的文档,evaluate(),execute() 用于评估、执行 JavaScript:http://help.eclipse.org/indigo/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/browser/Browser.html

这是我使用的代码:

import org.eclipse.swt.*;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.LocationEvent;
import org.eclipse.swt.browser.LocationListener;
import org.eclipse.swt.browser.ProgressEvent;
import org.eclipse.swt.browser.ProgressListener;
import org.eclipse.swt.browser.StatusTextEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
public class BrowserCodeDemo {

    public static void main(String[] args) {
        Display display = new Display();
        final Shell shell = new Shell(display);
        GridLayout gridLayout = new GridLayout();
        gridLayout.numColumns = 3;
        shell.setLayout(gridLayout);
        ToolBar toolbar = new ToolBar(shell, SWT.NONE);
        ToolItem itemBack = new ToolItem(toolbar, SWT.PUSH);
        itemBack.setText("Back");
        ToolItem itemForward = new ToolItem(toolbar, SWT.PUSH);
        itemForward.setText("Forward");
        ToolItem itemStop = new ToolItem(toolbar, SWT.PUSH);
        itemStop.setText("Stop");
        ToolItem itemRefresh = new ToolItem(toolbar, SWT.PUSH);
        itemRefresh.setText("Refresh");
        ToolItem itemGo = new ToolItem(toolbar, SWT.PUSH);
        itemGo.setText("Go");

        GridData data = new GridData();
        data.horizontalSpan = 3;
        toolbar.setLayoutData(data);

        Label labelAddress = new Label(shell, SWT.NONE);
        labelAddress.setText("Address");

        final Text location = new Text(shell, SWT.BORDER);
        data = new GridData();
        data.horizontalAlignment = GridData.FILL;
        data.horizontalSpan = 2;
        data.grabExcessHorizontalSpace = true;
        location.setLayoutData(data);

        final Browser browser;
        try {
            browser = new Browser(shell, SWT.NONE);
        } catch (SWTError e) {
            System.out.println("Could not instantiate Browser: " + e.getMessage());
            display.dispose();
            return;
        }
        data = new GridData();
        data.horizontalAlignment = GridData.FILL;
        data.verticalAlignment = GridData.FILL;
        data.horizontalSpan = 3;
        data.grabExcessHorizontalSpace = true;
        data.grabExcessVerticalSpace = true;
        browser.setLayoutData(data);

        final Label status = new Label(shell, SWT.NONE);
        data = new GridData(GridData.FILL_HORIZONTAL);
        data.horizontalSpan = 2;
        status.setLayoutData(data);

        final ProgressBar progressBar = new ProgressBar(shell, SWT.NONE);
        data = new GridData();
        data.horizontalAlignment = GridData.END;
        progressBar.setLayoutData(data);

        /* event handling */
        Listener listener = new Listener() {
            @Override
            public void handleEvent(Event event) {
                ToolItem item = (ToolItem)event.widget;
                String string = item.getText();
                if (string.equals("Back")) browser.back(); 
                else if (string.equals("Forward")) browser.forward();
                else if (string.equals("Stop")) browser.stop();
                else if (string.equals("Refresh")) browser.refresh();
                else if (string.equals("Go")) browser.setUrl(location.getText());
           }
        };
        browser.addProgressListener(new ProgressListener() {
            @Override
            public void changed(ProgressEvent event) {
                    if (event.total == 0) return;                            
                    int ratio = event.current * 100 / event.total;
                    progressBar.setSelection(ratio);
            }
            @Override
            public void completed(ProgressEvent event) {
                progressBar.setSelection(0);
            }
        });

        browser.addLocationListener(new LocationListener() {
            @Override
            public void changed(LocationEvent event) {
                if (event.top) location.setText(event.location);
            }
            @Override
            public void changing(LocationEvent event) 
            {
                //System.out.println("Something is happening.");
            }

        });
        itemBack.addListener(SWT.Selection, listener);
        itemForward.addListener(SWT.Selection, listener);
        itemStop.addListener(SWT.Selection, listener);
        itemRefresh.addListener(SWT.Selection, listener);
        itemGo.addListener(SWT.Selection, listener);
        location.addListener(SWT.DefaultSelection, new Listener() {
            @Override
            public void handleEvent(Event e) 
            {
                browser.setUrl(location.getText());
                System.out.println("New URL loaded");
            }
        });

        shell.open();
        browser.setUrl(
            "https://www.google.com/imghp?hl=en&tab=wi&ei=m8g4VLndMaz4igKlvoDADg&ved=0CAMQqi4oAQ");
        //browser.setVisible(false);
        boolean jQueryExecuted = browser.execute("$(\'#lst-ib\').val(\'snopes\')");
        if (!jQueryExecuted)
        {
            System.out.println("Your jQuery didn't execute.");
        }
        jQueryExecuted = browser.execute("$(\'[name=btnG]\').click()");
        if (!jQueryExecuted)
        {
            System.out.println("Your jQuery didn't execute.");
        }
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch())
                display.sleep();
        }

        display.dispose();

    }

}

我认为问题不在于代码本身,因为我尝试自动设置文本字段,但在 Java 和浏览器中都失败了; /* 文本字段的名称是“lst-ib” */

你想通过网络抓取什么?

我正在尝试从网络上抓取 Google 图片:https://www.google.com/imghp?hl=en&tab=wi&ei=m8g4VLndMaz4igKlvoDADg&ved=0CAMQqi4oAQ

文本字段是名称为“lst-ib”的输入。该按钮是一个名称为“btnG”的输入。文本字段位于 id 为“gs_lc0”的 div 中。 (我在那里也看到了多个其他输入元素,大小完全相同)。

【问题讨论】:

  • val(),由于某种原因,为输入字段返回未定义
  • 为什么没有人回应?

标签: java javascript jquery web-scraping


【解决方案1】:

哦,哇。已经10个小时了,除了我之外,没有人在这里发表过多评论。事实证明,问题比我想象的要大得多:Eclipse SWT 的浏览器无法执行 jQuery。

幸运的是,我发现了 Google Image API,它是用 JavaScript 编写的,已被弃用,但仍然有效。另外,我在页面上找到了一些简单的源代码:https://developers.google.com/image-search/v1/devguide#hiworld

我将newImg.src = "/image-search/v1/result.tbUrl;" 更改为newImg.src = result.tbUrl;,以便加载图像。这改变了一切。


你的新计划是什么?

我现在计划使用 Java 中的这段代码。我计划将 src 更改为 JavaScript 代码使用的 Google Image API 的 src,然后调用代码来获取前三个图像。显然,这就是您从 Java 运行 JavaScript 的方式:How to run javascript in java programming。如果我能弄清楚如何将 Java 使用的 JavaScript 引擎的 src 更改为此:https://www.google.com/jsapi

【讨论】:

  • 我可能会用 HTML 编写代码(基于我在这里谈到的 HTML),让 Java 将整个文件读入字符串,通过 @ 将浏览器 HTML 设置为该字符串987654326@ 然后,当用户单击按钮查找图像时,使用Browser.execute('userQuery'); 显示图像...
猜你喜欢
  • 1970-01-01
  • 2020-05-22
  • 1970-01-01
  • 1970-01-01
  • 2022-01-02
  • 2021-05-10
  • 1970-01-01
  • 2019-08-17
  • 1970-01-01
相关资源
最近更新 更多