有没有什么比Jsoup更快的HTML抓取?

时间:2012-04-24 04:31:55

标签: android jsoup

因此,我正在构建一个应用程序,该应用程序在我更方便用户界面的网站上显示图像板。目前它存在很多问题,但现在最大的问题是获取图像以显示它们。

我现在拥有它的方式,图像显示在大小为12的GridView中,反映了图像板每页上的图像数量。我正在使用Jsoup来抓取页面,以便在GridView中显示缩略图图像URL,以及获取用户点击缩略图时要显示的全尺寸图像的URL。

现在的问题是,Jsoup平均需要8-12秒来获取HTML页面。我发现这是不可接受的,我想知道是否有任何方法可以加快速度,或者这是否是一个我无法做任何事情的固有瓶颈。

这是我用来抓取页面的代码:

try {
    Document doc = Jsoup.connect(url).get();
    Elements links = doc.select("img[src*=/alt2/]");
    for (Element link : links) {
        thumbURL = link.attr("src");
        linkURL = thumbURL.replace("/alt2/", "/").replace("s.jpg", ".jpg");
        imgSrc.add(new Pair<String, String>(thumbURL, linkURL));
    }
}
catch {
    e.printStackTrace();
}

4 个答案:

答案 0 :(得分:6)

我使用Jsoup作为TLFN刮刀,我对速度没有任何问题。你应该缩小瓶颈。我认为你的刮擦是造成速度问题的原因。尝试分别跟踪您的选择器和网络流量,看看应该责怪哪个。如果您的选择器受到责备,那么请考虑寻找另一种查询方法并对结果进行基准测试。

为了更快,更一般的想法,测试你总是可以从普通的Java项目运行Jsoup,当你觉得你已经改进它时,把它扔回设备上,看看它是否有类似的性能改进。

修改

不是这是你的问题,但要注意使用迭代器'可以'导致相当多的垃圾收集触发。通常这不是一个问题,尽管如果你在很多重复使用它们的地方使用它们,它们可能会导致某些设备受到明显的性能影响。

不太好

for (Element link : links)

更好

int i;
Element tempLink;
for (i=0;i<links.size();i++) {
   tempLink = links.get(i);
}

编辑2

如果图片网址以/ alt2 /开头,您可以使用^ =代替* =,这可能会使搜索更快。此外,根据HTML的数量,您可能会浪费大量时间查看这些图像的完全错误的位置。检查这些图像是否包含在可识别的容器内,例如<div class="posts">。如果你可以缩小HTML的数量来筛选它可能会提高性能。

答案 1 :(得分:3)

虽然略有不同,但这个问题与Scraping dynamically generated html inside Android app的答案相同。

简而言之,您应该将“download&amp; parse”部分卸载到远程Web服务。有关讨论,请参阅Web Scraping from Android

查看Bobik,一个实时抓取平台,特别是this page

答案 2 :(得分:2)

我遇到了同样的问题:

我的HTC One S上的Logcat清楚地显示连接响应仅占用前4秒(并行3个连接)。解析需要将近30-40秒这是一个巨大的时间..注意HTC One S有一个非常快的双核@ 1,4ghz ..问题显然没有连接到模拟器

02-27 14:11:55.278: DEBUG/MyActivity(10735): =c>
02-27 14:11:55.278: DEBUG/MyActivity(10735): =c>
02-27 14:11:55.278: DEBUG/MyActivity(10735): =c>
02-27 14:11:59.002: DEBUG/MyActivity(10735): <r=
02-27 14:11:59.012: DEBUG/MyActivity(10735): <r=
02-27 14:11:59.422: DEBUG/MyActivity(10735): <r=
02-27 14:12:33.949: DEBUG/MyActivity(10735): <d=
02-27 14:12:37.463: DEBUG/MyActivity(10735): <d=
02-27 14:12:38.294: DEBUG/MyActivity(10735): <d=

这是我的代码:

// Jsoup-Connection
Connection c = Jsoup.connect(urls[0]);
// Request timeout in ms
c.timeout(5000);
Connection.Response r = c.execute();
Log.d("MyActivity","<r= doInBackground ("+urls[0]+")");

// Get the actual Document
Document doc = r.parse();
Log.d("MyActivity","<d= doInBackground ("+urls[0]+")");

<强>更新

02-27 20:38:25.649: INFO/MyActivity(18253): !=c> 
02-27 20:38:27.511: INFO/MyActivity(18253): !<r= 
02-27 20:38:28.873: INFO/MyActivity(18253): !#d=

我得到了一些新的结果.. previosu是在Android上运行我的应用程序 DEBUGGING ..现在发布的结果来自没有调试模式的运行(来自IntelliJ IDE)..任何解释为什么调试会让Jsoup这么慢?

在我的i5-Desktop-Machine上运行调试器我没有性能损失。

我的代码在Android上如此缓慢的罪魁祸首是 DEBUG-Mode 模式..它使jsoup减慢了100倍。

答案 3 :(得分:0)

您能否更好地识别您想要获得的内容,因为只有一个原因可能会降低您的代码执行速度

select("img[src*=/alt2/]")

您想要获得的图像是否有任何常见的“类”?