2

我正在使用 Java 和 htmlunit 的 WebClient 编写一个多线程刮板。我正在使用代理池,并且我有一个简单的类来处理它们。它有代理列表,您可以调用 GetProxy 函数来获取列表中下一个代理的 IP 和端口。我已经对其进行了彻底的测试,并且我已经确认它可以在任意数量的线程上按预期工作。

从那里我有一个 getHTML 函数,我可以在其中传递一个 URL 和一个代理,它会为我返回页面:

public String getHTML(String URL, ProxyData pData)
{
    WebClient webClient = new WebClient();
    String pageAsXml = "";

    webClient.setJavaScriptEnabled(false);

    ProxyConfig pConf = new ProxyConfig(pData._host, pData._port);
    webClient.setProxyConfig(pConf);

    try
    {
        HtmlPage page = webClient.getPage(URL);
        pageAsXml = page.asXml();
    }
    catch (FailingHttpStatusCodeException e)
    {
        e.printStackTrace();
    }
        catch (MalformedURLException e)
    {
        e.printStackTrace();
    }
        catch (IOException e)
    {
        e.printStackTrace();
    }

    webClient.closeAllWindows();

    return pageAsXml;
}

如果我在代码中设置 WebClients 代理设置后将它们写入控制台,它似乎是正确的 IP。在调试模式下单步执行也证实了这一点。但是,返回的结果 HTML 似乎并未反映更改后的代理。

我正在使用 WhatIsMyIP 的自动化页面来检查我的代理以查看它们是否正常工作 (http://automation.whatismyip.com/n09230945.asp)。每次我得到一个页面后,我都会编写传递给函数的代理,代理 WebClient 说它在页面加载时正在使用,然后在 HTML 中返回的代理到控制台。前两个总是匹配得很好,但返回的 IP 是关闭的。他们第一次都是正确的,但随后他们似乎开始重用代理。并且代理并不总是在同一个线程中被重用。他们似乎只是选择了一个已经存在的随机代理。

似乎代理在被实际替换之前被随机重用了一段时间,甚至跨线程。即使我设置了一个新的代理,并且 WebClient 似乎知道我已经设置了一个新的代理,但它似乎仍然使用旧的代理。

那么是什么原因造成的,我该如何解决呢?

4

1 回答 1

1

这里有一个框架,它基本上通过 htmlunit 为您在代理池上执行多线程:https ://github.com/subes/invesdwin-webproxy

它还解决了其他问题,例如 htmlunits javascript 解析器实例过多耗尽 cpu 和其他问题。也许代码可以提示您在自己的框架中以这种方式使用 htmlunit 时可以做哪些不同的事情。

于 2017-06-25T18:12:14.187 回答