網頁可以透過meta標籤的charset來設定網頁編碼,譬如:
<meta charset="utf-8" />
我們右鍵,查看頁面原始碼:
可以看到,知乎採用的是UTF-8編碼。
在這裡和大家解釋一下查看頁面原始碼和審查元素的差異。
查看頁面源代碼是顯示整個頁面的所有代碼,沒有按照HTML的標籤進行排版,相當於是直接查看源碼,這種方式對於查看整個網頁的信息,比如meta比較有用。
審查元素,或有的瀏覽器叫查看元素,是針對你右鍵的元素進行查看,例如一個div或img,比較適用於單獨查看某個物件的屬性和標籤。
好的,我們現在知道了問題出在了編碼上,接下來就是對抓取到的內容進行編碼轉換了。
在java中實作很簡單,只需要在InputStreamReader裡面指定編碼方式就行:
// 初始化 BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader( connection.getInputStream(),"UTF-8"));
此時再運行程序,便會發現可以正常顯示標題了:
好的!非常好!
但是現在才只有一個標題,我們需要的是所有的標題。
我們將正則稍加修改,把搜索到的結果存儲到一個ArrayList裡面:
import java.io.*; import java.net.*; import java.util.ArrayList; import java.util.regex.*; public class Main { static String SendGet(String url) { // 定义一个字符串用来存储网页内容 String result = ""; // 定义一个缓冲字符输入流 BufferedReader in = null; try { // 将string转成url对象 URL realUrl = new URL(url); // 初始化一个链接到那个url的连接 URLConnection connection = realUrl.openConnection(); // 开始实际的连接 connection.connect(); // 初始化 BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader( connection.getInputStream(), "UTF-8")); // 用来临时存储抓取到的每一行的数据 String line; while ((line = in.readLine()) != null) { // 遍历抓取到的每一行并将其存储到result里面 result += line; } } catch (Exception e) { System.out.println("发送GET请求出现异常!" + e); e.printStackTrace(); } // 使用finally来关闭输入流 finally { try { if (in != null) { in.close(); } } catch (Exception e2) { e2.printStackTrace(); } } return result; } static ArrayList<String> RegexString(String targetStr, String patternStr) { // 预定义一个ArrayList来存储结果 ArrayList<String> results = new ArrayList<String>(); // 定义一个样式模板,此中使用正则表达式,括号中是要抓的内容 Pattern pattern = Pattern.compile(patternStr); // 定义一个matcher用来做匹配 Matcher matcher = pattern.matcher(targetStr); // 如果找到了 boolean isFind = matcher.find(); // 使用循环将句子里所有的kelvin找出并替换再将内容加到sb里 while (isFind) { //添加成功匹配的结果 results.add(matcher.group(1)); // 继续查找下一个匹配对象 isFind = matcher.find(); } return results; } public static void main(String[] args) { // 定义即将访问的链接 String url = "http://www.zhihu.com/explore/recommendations"; // 访问链接并获取页面内容 String result = SendGet(url); // 使用正则匹配图片的src内容 ArrayList<String> imgSrc = RegexString(result, "question_link.+?>(.+?)<"); // 打印结果 System.out.println(imgSrc); } }
這樣就能匹配到所有的結果了(因為直接打印了ArrayList所以會有一些中括號和逗號