知乎脚丫第二弹

有了前一篇的Google首页logo链接抓取的经验,学会了怎样向网页发送GET请求、字符串存储整个网页源码、正则表达式的初级使用。在这些基础上,可以开始玩耍了。
需求:知乎发现页面上有编辑推荐、今日最热和本月最日的一些问题和回答。我们要把这些问题及问题的链接,还有回答给抓取下来。

获取整个网页的信息

为了简洁优雅,把发送请求,获取源码信息写成一个静态方法static ReadGet(String url),返回字符串.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
static String ReadGet(String url) {  
// 定义一个字符串用来存储网页内容
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"));//查看了知乎使用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;
}

有了网页都所有信息,就可以抓去所需要的信息。

到底要抓什么

比较
从图中红色框中可以看出,对于论述性话题,源码是post-link打头,而对于提问,源码是question-link这两者有很好的区分。我们要抓取的就是提问“有哪些小技能是可以通过闲暇时间学到的?”和该提问的链接“/question/36267481/answer/107978739”。

正则表达式高阶用法

这里提一笔,正则表达式的分组和捕获的用法吧(因为把我也弄逼了),来…来…给个传送门《 JAVA正则表达式高级用法(分组与捕获)》里面详细讲解了原理,就知道要你们喊的。这里我也就用用,知道group(0),group(1)的区别,group(0)是整个表达式,group(1)表示被第一个括号括起来的组——引自《java编程思想》。
所以说,匹配提问的正则是question_link.+?>(.+?)<,而匹配提问的地址是question_link.+?href=\"(.+?)\"

1
2
3
4
5
6
7
8
9
10
//测试
static ArrayList<String> getQuestion(String content){
ArrayList<String> res=new ArrayList<String>();
Pattern p=Pattern.compile("question_link.+?>(.+?)<");
Matcher m=p.matcher(content);
while(m.find()){//这里讲解一下java正则高阶用法,分组和捕获
res.add(m.group(1)+'\n');//group(1)表示被第一个括号括起来的组——引自《java编程思想》
}
return res;
}

result
上面就是抓到提问标题信息。
接下来测试抓提问链接,其实也就是改一下正则表达式。

1
2
3
4
5
6
7
8
9
10
//测试
static ArrayList<String> getQuestion(String content){
ArrayList<String> res=new ArrayList<String>();
Pattern p=Pattern.compile("question_link.+?href=\"(.+?)\"");//修改成匹配链接地址
Matcher m=p.matcher(content);
while(m.find()){//这里讲解一下java正则高阶用法,分组和捕获
res.add(m.group(1)+'\n');//group(1)表示被第一个括号括起来的组——引自《java编程思想》
}
return res;
}

enter description here
好了,今天就写到这,下面就是把抓取到的这两部分整合到一起,这个好办,写一个类带两个字段,把提问和提问链接放进去。但是回答不在同一个网页里怎么爬呢?这是个思考的问题。

热评文章