Zhihu adalah komunitas Tanya Jawab online nyata dengan suasana komunitas yang ramah, rasional, dan serius yang menghubungkan para elit dari semua lapisan masyarakat. Mereka saling berbagi pengetahuan, pengalaman, dan wawasan profesional, serta terus memberikan informasi berkualitas tinggi untuk Internet Tiongkok.
Pertama, luangkan waktu tiga hingga lima menit untuk mendesain Logo =. =Sebagai seorang programmer, saya selalu mempunyai hati untuk menjadi seorang seniman!
Oke, ini sedikit darurat, jadi saya akan menyelesaikannya sekarang.
Selanjutnya, kami mulai membuat crawler Zhihu.
Pertama, tentukan tujuan pertama: rekomendasi editor.
Tautan web: http://www.zhihu.com/explore/recommendations
Kami sedikit memodifikasi kode terakhir untuk terlebih dahulu mencapai kemampuan mendapatkan konten halaman:
import java.io.*;
impor java.net.*;
import java.util.regex.*;
kelas publik Utama {
String statis SendGet(String url) {
//Tentukan string untuk menyimpan konten halaman web
Hasil string = "";
//Tentukan aliran input karakter yang di-buffer
BufferedReader di = null;
mencoba {
//Konversi string menjadi objek url
URL realUrl = URL baru(url);
// Inisialisasi tautan ke url itu
Koneksi URLConnection = realUrl.openConnection();
// Mulai koneksi sebenarnya
koneksi.koneksi();
//Inisialisasi aliran input BufferedReader untuk membaca respons URL
di = BufferedReader baru(InputStreamReader baru(
koneksi.getInputStream()));
// Digunakan untuk menyimpan sementara data dari setiap baris yang diambil
garis senar;
while ((baris = masuk.readLine()) != null) {
// Lintasi setiap baris yang diambil dan simpan sebagai hasilnya
hasil += baris;
}
} tangkapan (Pengecualian e) {
System.out.println("Terjadi pengecualian saat mengirimkan permintaan GET!" + e);
e.printStackTrace();
}
// Gunakan akhirnya untuk menutup aliran input
Akhirnya {
mencoba {
jika (dalam != nol) {
melampirkan();
}
} tangkapan (Pengecualian e2) {
e2.printStackTrace();
}
}
hasil pengembalian;
}
String statis RegexString(String targetStr, String patternStr) {
// Tentukan template gaya, menggunakan ekspresi reguler, dan konten yang akan diambil ada dalam tanda kurung
// Ini sama dengan mengubur jebakan dan akan jatuh jika cocok.
Pola pola = Pattern.compile(patternStr);
//Tentukan pencocokan untuk pencocokan
Pencocokan pencocok = pattern.matcher(targetStr);
// jika ditemukan
if (pencocokan.temukan()) {
// cetak hasilnya
return matcher.group(1);
}
kembalikan "Tidak Ada";
}
public static void main(String[] args) {
// Tentukan link yang akan dikunjungi
String url = "http://www.zhihu.com/explore/recommendations";
//Akses tautan dan dapatkan konten halaman
Hasil string = SendGet(url);
// Gunakan ekspresi reguler untuk mencocokkan konten src gambar
//String imgSrc = RegexString(hasil, "src=/"(.+?)/"");
// mencetak hasil
System.out.println(hasil);
}
}
Tidak ada masalah setelah menjalankannya. Langkah selanjutnya adalah masalah pencocokan biasa.
Pertama, mari kita dapatkan semua pertanyaan di halaman ini.
Klik kanan pada judul dan periksa elemennya:
Aha, terlihat bahwa judul sebenarnya adalah tag a yang merupakan hyperlink, dan yang dapat dibedakan dengan hyperlink lainnya adalah kelasnya, yang merupakan pemilih kelas.
Jadi pernyataan reguler kami keluar: question_link.+?href=/"(.+?)/"
Panggil fungsi RegexString dan berikan parameternya:
public static void main(String[] args) {
// Tentukan link yang akan dikunjungi
String url = "http://www.zhihu.com/explore/recommendations";
//Akses tautan dan dapatkan konten halaman
Hasil string = SendGet(url);
// Gunakan ekspresi reguler untuk mencocokkan konten src gambar
String imgSrc = RegexString(hasil, "question_link.+?>(.+?)<");
// mencetak hasil
Sistem.keluar.println(imgSrc);
}
Ah ha, Anda dapat melihat bahwa kami berhasil mendapatkan sebuah judul (catatan, hanya satu):
Tunggu sebentar, ada apa dengan semua kekacauan ini? !
Jangan gugup=. =Itu hanya karakter yang kacau.
Untuk masalah pengkodean, silakan lihat: Kumpulan karakter HTML
Secara umum, pengkodean mainstream dengan dukungan yang lebih baik untuk bahasa Mandarin adalah pengkodean UTF-8, GB2312 dan GBK.
Halaman web dapat mengatur pengkodean halaman web melalui rangkaian karakter tag meta, misalnya:
<meta charset="utf-8" />
Mari klik kanan untuk melihat kode sumber halaman:
Seperti yang Anda lihat, Zhihu menggunakan pengkodean UTF-8.
Di sini saya akan menjelaskan kepada Anda perbedaan antara melihat kode sumber halaman dan memeriksa elemen.
Melihat kode sumber halaman menampilkan semua kode dari keseluruhan halaman. Ini tidak diformat menurut tag HTML. Ini sama dengan melihat kode sumber secara langsung. Cara ini lebih berguna untuk melihat informasi seluruh halaman web, seperti meta.
Periksa elemen, atau beberapa browser menyebutnya elemen tampilan, yaitu untuk melihat elemen yang Anda klik kanan, seperti div atau img. Ini lebih cocok untuk melihat atribut dan tag suatu objek satu per satu.
Oke, sekarang kita tahu masalahnya terletak pada pengkodean, langkah selanjutnya adalah mengubah pengkodean konten yang diambil.
Implementasinya di java sangat sederhana, cukup tentukan metode pengkodean di InputStreamReader:
//Inisialisasi aliran input BufferedReader untuk membaca respons URL
di = BufferedReader baru(InputStreamReader baru(
koneksi.getInputStream(),"UTF-8"));
Jika Anda menjalankan kembali program saat ini, Anda akan menemukan bahwa judul dapat ditampilkan secara normal:
OKE! sangat bagus!
Tapi sekarang hanya ada satu gelar, kami butuh semua gelar.
Kami sedikit memodifikasi ekspresi reguler dan menyimpan hasil pencarian di ArrayList:
import java.io.*;
impor java.net.*;
impor java.util.ArrayList;
import java.util.regex.*;
kelas publik Utama {
String statis SendGet(String url) {
//Tentukan string untuk menyimpan konten halaman web
Hasil string = "";
//Tentukan aliran input karakter yang di-buffer
BufferedReader di = null;
mencoba {
//Konversi string menjadi objek url
URL realUrl = URL baru(url);
// Inisialisasi tautan ke url itu
Koneksi URLConnection = realUrl.openConnection();
// Mulai koneksi sebenarnya
koneksi.koneksi();
//Inisialisasi aliran input BufferedReader untuk membaca respons URL
di = BufferedReader baru(InputStreamReader baru(
koneksi.getInputStream(), "UTF-8"));
// Digunakan untuk menyimpan sementara data dari setiap baris yang diambil
garis senar;
while ((baris = masuk.readLine()) != null) {
// Lintasi setiap baris yang diambil dan simpan sebagai hasilnya
hasil += baris;
}
} tangkapan (Pengecualian e) {
System.out.println("Terjadi pengecualian saat mengirimkan permintaan GET!" + e);
e.printStackTrace();
}
// Gunakan akhirnya untuk menutup aliran input
Akhirnya {
mencoba {
jika (dalam != nol) {
melampirkan();
}
} tangkapan (Pengecualian e2) {
e2.printStackTrace();
}
}
hasil pengembalian;
}
static ArrayList<String> RegexString(String targetStr, String patternStr) {
// Tentukan terlebih dahulu ArrayList untuk menyimpan hasilnya
Hasil ArrayList<String> = ArrayList<String>();
// Tentukan template gaya, menggunakan ekspresi reguler, dan konten yang akan diambil ada dalam tanda kurung
Pola pola = Pattern.compile(patternStr);
//Tentukan pencocokan untuk pencocokan
Pencocokan pencocok = pattern.matcher(targetStr);
// jika ditemukan
boolean isFind = matcher.find();
// Gunakan loop untuk menemukan dan mengganti semua kelvin dalam kalimat dan menambahkan konten ke sb
sementara (isFind) {
//Tambahkan hasil pencocokan yang berhasil
hasil.tambahkan(matcher.grup(1));
// Lanjutkan untuk menemukan objek berikutnya yang cocok
isFind = matcher.find();
}
mengembalikan hasil;
}
public static void main(String[] args) {
// Tentukan link yang akan dikunjungi
String url = "http://www.zhihu.com/explore/recommendations";
//Akses tautan dan dapatkan konten halaman
Hasil string = SendGet(url);
// Gunakan ekspresi reguler untuk mencocokkan konten src gambar
ArrayList<String> imgSrc = RegexString(hasil, "question_link.+?>(.+?)<");
// mencetak hasil
Sistem.keluar.println(imgSrc);
}
}
Ini akan cocok dengan semua hasil (karena ArrayList dicetak langsung, akan ada beberapa tanda kurung siku dan koma):
Oke, ini adalah langkah pertama perayap Zhihu.
Namun kita dapat melihat bahwa tidak ada cara untuk menangkap semua pertanyaan dan jawaban dengan cara ini.
Kita perlu merancang kelas enkapsulasi Zhihu untuk menyimpan semua objek yang diambil.
Kode sumber Zhihu.java:
impor java.util.ArrayList;
kelas publik Zhihu {
pertanyaan String publik; // pertanyaan
String publik zhihuUrl;//Tautan halaman web
public ArrayList<String> jawaban; // Array untuk menyimpan semua jawaban
// Konstruktor menginisialisasi data
Zhihu publik() {
pertanyaan = "";
zhihuUrl = "";
jawaban = Daftar Array baru<String>();
}
@Mengesampingkan
String publik keString() {
return "Pertanyaan:" + pertanyaan + "/nLink:" + zhihuUrl + "/nAnswer:" + jawaban + "/n";
}
}
Buat kelas Spider baru untuk menyimpan beberapa fungsi crawler yang umum digunakan.
Kode sumber Spider.java:
impor java.io.BufferedReader;
impor java.io.InputStreamReader;
impor java.net.URL;
impor java.net.URLConnection;
impor java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
laba-laba kelas publik {
String statis SendGet(String url) {
//Tentukan string untuk menyimpan konten halaman web
Hasil string = "";
//Tentukan aliran input karakter yang di-buffer
BufferedReader di = null;
mencoba {
//Konversi string menjadi objek url
URL realUrl = URL baru(url);
// Inisialisasi tautan ke url itu
Koneksi URLConnection = realUrl.openConnection();
// Mulai koneksi sebenarnya
koneksi.koneksi();
//Inisialisasi aliran input BufferedReader untuk membaca respons URL
di = BufferedReader baru(InputStreamReader baru(
koneksi.getInputStream(), "UTF-8"));
// Digunakan untuk menyimpan sementara data dari setiap baris yang diambil
garis senar;
while ((baris = masuk.readLine()) != null) {
// Lintasi setiap baris yang diambil dan simpan sebagai hasilnya
hasil += baris;
}
} tangkapan (Pengecualian e) {
System.out.println("Terjadi pengecualian saat mengirimkan permintaan GET!" + e);
e.printStackTrace();
}
// Gunakan akhirnya untuk menutup aliran input
Akhirnya {
mencoba {
jika (dalam != nol) {
melampirkan();
}
} tangkapan (Pengecualian e2) {
e2.printStackTrace();
}
}
hasil pengembalian;
}
static ArrayList<Zhihu> GetZhihu(Konten string) {
// Tentukan terlebih dahulu ArrayList untuk menyimpan hasilnya
ArrayList<Zhihu> hasil = ArrayList<Zhihu>();
// Digunakan untuk mencocokkan judul
Pola questionPattern = Pattern.compile("question_link.+?>(.+?)<");
Pencocokan questionMatcher = questionPattern.matcher(konten);
// Digunakan untuk mencocokkan url yang merupakan link ke pertanyaan
Pola urlPattern = Pattern.compile("question_link.+?href=/"(.+?)/"");
Pencocokan urlMatcher = urlPattern.matcher(konten);
// Pertanyaan dan tautannya harus cocok
boolean isFind = questionMatcher.find() && urlMatcher.find();
sementara (isFind) {
//Tentukan objek Zhihu untuk menyimpan informasi yang diambil
Zhihu zhuhuTemp = Zhihu baru();
zhuhuTemp.question = questionMatcher.group(1);
zhuhuTemp.zhihuUrl = "http://www.zhihu.com" + urlMatcher.group(1);
//Tambahkan hasil pencocokan yang berhasil
hasil.tambahkan(zhuhuTemp);
// Lanjutkan untuk menemukan objek berikutnya yang cocok
isFind = questionMatcher.find() && urlMatcher.find();
}
mengembalikan hasil;
}
}
Metode utama terakhir bertanggung jawab untuk menelepon.
impor java.util.ArrayList;
kelas publik Utama {
public static void main(String[] args) {
// Tentukan link yang akan dikunjungi
String url = "http://www.zhihu.com/explore/recommendations";
//Akses tautan dan dapatkan konten halaman
Konten string = Spider.SendGet(url);
// Dapatkan semua objek Zhihu di halaman ini
ArrayList<Zhihu> myZhihu = Spider.GetZhihu(konten);
// mencetak hasil
Sistem.keluar.println(myZhihu);
}
}
Oke, itu saja. Jalankan dan lihat hasilnya:
Hasil yang bagus.
Langkah selanjutnya adalah mengakses tautan dan mendapatkan semua jawabannya.
Kami akan memperkenalkannya lain kali.
Oke, di atas adalah pengenalan singkat keseluruhan proses cara menggunakan Java untuk menangkap konten yang direkomendasikan oleh editor Zhihu, sangat detail dan mudah dipahami, Teman-teman yang membutuhkan bisa merujuk dan mengembangkannya dengan bebas