这是合约。在我的Android应用程序中,我正在使用Jsoup进行一些网络抓取。现在它工作正常,但它太慢了。我在代码中所做的是:
现在问题是它速度很快。我的意思是,在按下登录按钮后,在应用程序的登录界面中,用户必须在3G中等待10秒,在WiFi中等待8-10秒(取决于WiFi速度)。当他试图检查数据更新时,它会执行相同的算法+比较SQLiteDatabase表数据。
那么,有没有其他方法来做这个HTML解析 - 在android中刮掉东西以使其更快?附:我遗憾地无法访问数据库。
修改
由于您询问了我正在抓取的内容,以下是您可以在不登录的情况下访问的几个页面的一个示例(与其他人相比,这不是一个很大的表格):https://medeine.vgtu.lt/programos/programa.jsp?sid=F&fak=5&prog=87&rus=U&klb=en。
现在,对于代码......我真的不能给你完整的代码,但这里是我得到表的每个单元格的例子:
document = Jsoup.connect(getContext().getString(R.string.url))
.cookie("JSESSIONID", cookie)
.get();
Element table = document.select("table.duomenys").first();
if (table != null) {
databaseHandler.openDatabase();
databaseHandler.getDatabase().beginTransaction();
try {
for (Element row : table.select("tr.n, tr.l") {
Elements columns = row.select("td");
addItem(columns, DatabaseHandler.getTableName());
}
databaseHandler.getDatabase().setTransactionSuccessful();
} finally {
databaseHandler.getDatabase().endTransaction();
}
databaseHandler.closeDatabase();
}
这是addItem()方法示例:
private void addItem(Elements columns, String tableName) {
databaseHandler.addItem(new Item(
columns.get(0).text(),
columns.get(1).text(),
columns.get(3).text(),
columns.get(4).text()
), tableName);
}
这只是一页。其中有6个,其中很少有更大。当然这是在AsyncTaskLoader的loadInBackground()方法中完成的。
编辑2:
Connection.Response response = Jsoup.connect("https://medeine.vgtu.lt/studentams/submit.jsp")
.data("studKnNr", id, "asmKodas", password)
.timeout(3000)
.method(Connection.Method.POST)
.execute();
String cookie = response.cookie("JSESSIONID");
Document document = Jsoup.connect(modules_url)
.cookie(cookie_id, cookie)
.get();
当我想到它时...可能是解析不是很慢,而是登录并重定向到6页,在这种情况下我什么都不做?现在我注意到在Connection.Response中通过.execute()向服务器发送POST并获取cookie需要大约2.5秒。
答案 0 :(得分:5)
由于您的问题含糊不清,并且您没有提供代码,也没有提供您正在解析的DOM的一些示例,我将提供一般答案。
StringBuilder
代替String
。<强>更新强>
您可以接收服务器的响应,操纵消息正文,然后使用Jsoup的解析,这样您就可以最小化解析的时间。
try {
Connection.Response response = Jsoup.connect("ENTER_URL")
.userAgent("Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0")
.referrer("http://www.google.com")
.method(Method.GET) //or Method.POST
.execute();
String body = response.body();
String table = body; //Manipulate the string, remove all the data you don't want.
Document doc = Jsoup.parse(table);
System.out.println(doc);
} catch(Exception e) {
e.printStackTrace();
}
更新2
Connection.Response line takes 2.6 seconds
:这无济于事。你必须忍受这个,因为服务器延迟服务你的请求。毕竟你只使用一次cookie然后重复使用它们。
但是,此部分getting the page
可以在某种程度上进行优化。如果你使用我发布的代码,你仍然会有再次发出http请求的开销(这是无法避免的,这是与cookie一样的服务器延迟),但你只会解析你需要的部分,而不是整个回应。这会给你一些改进,但我不相信它会有多大改进。也许它甚至不值得。但您可以尝试仅更改此部分,并告诉我您是否看到任何改进。
Document document = Jsoup.connect(modules_url)
.cookie(cookie_id, cookie)
.get();
此外,如果你真的需要速度,你将不得不使用某种形式的并发(多线程)。 这样的事情会产生真正的不同:
Check this选择了如何使您的http请求并发的答案