在互联网时代,知乎因独特的社区环境和大量优质内容而广受欢迎。而且,技术爱好者对从知乎抓取数据的尝试也颇具乐趣。
知乎社区氛围的独特魅力
知乎汇聚了众多行业翘楚。在诸如北京、上海等一线城市,众多专业人士在此活跃,他们于闲暇时分共享知识。这种交流让众多处于职场困境的年轻人受益匪浅。比如,一位在深圳求职屡屡碰壁的大学生,通过知乎上一位职场人士的面试指导,成功找到了工作。在知乎,人们理性沟通,友好互动,这种氛围促进了知识的传播。同时,这种高品质的分享使得知乎在中文互联网中成为了一个知识宝库。
import java.io.*;
import java.net.*;
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()));
// 用来临时存储抓取到的每一行的数据
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 String RegexString(String targetStr, String patternStr) {
// 定义一个样式模板,此中使用正则表达式,括号中是要抓的内容
// 相当于埋好了陷阱匹配的地方就会掉下去
Pattern pattern = Pattern.compile(patternStr);
// 定义一个matcher用来做匹配
Matcher matcher = pattern.matcher(targetStr);
// 如果找到了
if (matcher.find()) {
// 打印出结果
return matcher.group(1);
}
return "Nothing";
}
public static void main(String[] args) {
// 定义即将访问的链接
String url = "http://www.zhihu.com/explore/recommendations";
// 访问链接并获取页面内容
String result = SendGet(url);
// 使用正则匹配图片的src内容
//String imgSrc = RegexString(result, "src="(.+?)"");
// 打印结果
System.out.println(result);
}
}
社区中弥漫着友好、理性、认真的气氛,这种氛围与社区的管理紧密相连。知乎制定了众多规章制度,用以维持这种积极的氛围,比如对恶意攻击他人、发布低质量内容的行为,都有严格的规定和处罚。这些措施确保了社区内的分享内容大多是积极向上、富有价值的。
作为程序员的别样心思
许多程序员怀揣跨界梦想,文中提及的程序员想转行做美工便是其中一例。实际上,程序员的工作往往较为单调,他们渴望像美工那样富有创意。以某些互联网公司为例,程序员每天大部分时间都在与代码为伍。有位程序员在欣赏了大量美工制作的精美网页后,对美工职业产生了极大兴趣。他开始利用业余时间学习美工相关知识,但由于缺乏专业基础,其成果只能算是一般。然而,这种敢于尝试新事物的精神值得赞扬,也体现了当代职场人士对多元化发展的追求。
public static void main(String[] args) {
// 定义即将访问的链接
String url = "http://www.zhihu.com/explore/recommendations";
// 访问链接并获取页面内容
String result = SendGet(url);
// 使用正则匹配图片的src内容
String imgSrc = RegexString(result, "question_link.+?>(.+?)<");
// 打印结果
System.out.println(imgSrc);
}
企业里对跨界尝试的看法各有不同。有的公司支持员工跨领域学习,并开设了专项培训。但有些小公司因为资源不足,更注重员工本职工作的完成。
知乎爬虫的第一步
制作知乎爬虫,第一步是明确目标,这里指的是从编辑推荐开始。编写代码时,需要不断调整以抓取网页信息。以一家小型创业公司为例,若他们想开发一款整理知乎热门话题的软件,爬虫技术便是关键。起初,在获取网页内容时遇到了不少难题。这其实是一个不断调试和修改的过程,就好比艺术家精心雕琢自己的作品。
获取页面上的问题并进行规则匹配是关键步骤之一。要准确识别超链接的class属性,必须仔细检查相关元素。新手需要掌握HTML的基础知识。例如,一个正在自学编程的学生在处理这部分内容时,花费了大量时间来弄懂各种标签的功能。
编码问题剖析
在制作爬虫时,编码问题常被忽视,实则至关重要。有些网站显示中文效果不佳,原因往往在于编码不匹配。比如,之前抓取知乎编辑推荐内容的程序就遇到了乱码问题。要解决这个问题,首先要弄清楚网页所用的编码。多数现代网站,包括知乎,都采用UTF-8编码。
我们得知,弄清查看网页源码和审查元素的不同之处,对解决编程难题大有裨益。有位热衷于网页开发的爱好者投入了相当多的时间去区分这两种查看方法,这对精确找出并解决编程中的问题起到了重要作用。
// 初始化 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
connection.getInputStream(),"UTF-8"));
完善爬虫抓取全部标题
单抓一个标题显然不够用。于是,调整正则表达式成了下一项任务。将匹配到的结果保存在特定格式里,就能顺利拿到所有标题。这个过程就像渔夫换了个更大的网,能捞到更多的鱼。
对抓取到的信息进行编码转换,是确保标题正常显示的核心。不同编程语言中,这一过程的具体做法各异。文中以Java为例,其实现过程相对简便。对于从事数据采集工作的人来说,掌握这一技能是必不可少的。
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 RegexString(String targetStr, String patternStr) {
// 预定义一个ArrayList来存储结果
ArrayList results = new ArrayList();
// 定义一个样式模板,此中使用正则表达式,括号中是要抓的内容
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 imgSrc = RegexString(result, "question_link.+?>(.+?)<");
// 打印结果
System.out.println(imgSrc);
}
}
构建封装类以扩展功能
为了获取更多数据,包括所有问题和回答,我们必须创建一个知乎封装类以及一个用于存放爬虫常用函数的类。这样的设计能让程序更模块化,便于维护和扩展。一个小的软件开发团队在开展知乎数据搜集项目时,采用了类似的方法,显著提升了开发速度。程序的核心部分——main方法,负责启动整个流程。尽管目前还无法完整抓取知乎的全部信息,但我们已经取得了几个关键进展。