Crawl Data from Html
Bài đăng này đã không được cập nhật trong 3 năm
Nhiều khi chúng ta muốn lấy dữ liệu trên các trang web, ví dụ lấy truyện, bài báo,ảnh hoặc get link nhạc từ các trang nghe nhạc trực tuyến.... Nếu những dữ liệu đó được hiển thị trên trang web, thì hoàn toàn có thể lấy được. Ở đây mình sẽ sử dụng Jsoup để lấy 1 số dữ liệu đơn giản trên web
Đầu tiên cần xem mã nguồn của trang web đó, ở đây mình sẽ ví dụ là trang web http://khongphailanhatky.blogspot.com/2015/11/test.html
Sau đó cần xác định 1 số thông tin để xác định chính xác chỗ cần lấy thông tin,
ở đây mình sẽ xác định id của bài viết cần crawl về, bên trong thẻ này có 3 thẻ <category>, <title> và <content>. Như vậy là đã xác định xong các thành phần cần lấy thông tin, tiếp theo sẽ thực hiện code chương trình.
Đầu tiên khai báo INTERNET permission trong Manifest, và import thư viện Jsoup:
Sau đó tạo layout trong activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv_category"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textSize="20sp"
android:textStyle="bold|italic" />
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:textSize="15sp" />
</LinearLayout>
</ScrollView>
</LinearLayout>
Tiếp theo là sử dụng Jsoup để get html code về và parse để lấy thông tin trong MainActivity Thứ tự các bước sẽ là:
- Lấy toàn bộ html trang web về
- Tìm trong đó element chứa bài viết
- Lấy các thông tin trong bài viết và hiển thị, (thông tin trong các thẻ <category>, <title>, <content>)
public class MainActivity extends AppCompatActivity {
private ProgressDialog progressDialog;
private TextView tvCategory;
private TextView tvTitle;
private TextView tvContent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
progressDialog = new ProgressDialog(this);
tvCategory = (TextView) findViewById(R.id.tv_category);
tvTitle = (TextView) findViewById(R.id.tv_title);
tvContent = (TextView) findViewById(R.id.tv_content);
String path = "http://khongphailanhatky.blogspot.com/2015/11/test.html";
String idPost = "post-body-8881203422069576330";
URL url;
try {
url = new URL(path);
} catch (MalformedURLException e) {
e.printStackTrace();
Toast.makeText(this, "URL is invalid", Toast.LENGTH_SHORT).show();
return;
}
GetContentFromURL getContentFromURL = new GetContentFromURL(url, idPost);
getContentFromURL.execute();
}
private class GetContentFromURL extends AsyncTask<Void, Void, Document> {
private URL url;
private String idPost;
public GetContentFromURL(URL url, String idPost) {
this.url = url;
this.idPost = idPost;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog.setMessage("Please wait ...");
progressDialog.setCancelable(false);
progressDialog.show();
}
@Override
protected Document doInBackground(Void... params) {
try {
Document elements = Jsoup.connect(url.toString()).get();
return elements;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
@Override
protected void onPostExecute(Document document) {
super.onPostExecute(document);
if (document != null) {
Element element = Jsoup.parse(document.toString()).select("#" + idPost).first();
Elements listElement = element.getAllElements();
String category = "", title = "", content = "";
for (int i = 0; i < listElement.size(); i++) {
Element childElement = listElement.get(i);
switch (childElement.tagName()) {
case "category":
if (childElement.hasText()) {
category = childElement.text();
}
break;
case "title":
title = childElement.text();
break;
case "content":
String outputText = childElement.text();
String inputTextStart = outputText.replace("\\n ", "\n");
String inputTextFinal = inputTextStart.replace("\\n", "\n");
content = inputTextFinal;
break;
}
}
tvCategory.setText(category);
tvTitle.setText(title);
tvContent.setText(content);
} else {
Toast.makeText(MainActivity.this, "Get Data Fail", Toast.LENGTH_SHORT).show();
}
progressDialog.dismiss();
}
}
Một điều cần chú ý là nếu find theo id thì trước key cần có ký tự '#'. Tham khảo use selector tại http://jsoup.org/cookbook/extracting-data/selector-syntax
Kết quả:
Thank you for reading, happy cold day to everyone!
All rights reserved