言归正传,我准备写一个百度贴吧爬虫给他,为了方便,使用jsoup来进行解析爬取。
用我们学校贴吧进行试验(桂林理工大学吧),这个只是个简单的试验品,不喜勿喷。
使用jsoup来进行解析爬取。
- Document doc = Jsoup.connect("http://tieba.baidu.com/f?ie=utf-8&kw=%E9%83%91%E7%A7%80%E5%A6%8D")//桂工吧网址
- .userAgent( "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.15)")
- .timeout(3000) // 设置连接超时时间
- .get(); // 使用 GET 方法访问 URL
用Chrome浏览器打开桂工吧官网,按下F12键,搜索一个帖子,如图所示
<a href="/p/4201959797"我们要在总吧里找到帖子的超链接,上面的 "/p/4201959797"就是我们需要找的数据
用如下代码就可以找到,Elements baiduPost=doc.select("a.j_th_tit");,a表示匹配<a>超链接标签, .j_th_tit是标签里的类,所以doc.select(a.j_th_tit)的意思就是寻找所有<a>标签里有a.j_th_tit类的html
</pre><pre name="code" class="java"><span style="white-space:pre"> </span>Elements baiduPost=doc.select("a.j_th_tit");//总贴吧帖子url
System.out.println(baiduPost.attr("href"));
输出如下(其实匹配了所有的出来,我这里只输出一个)
得到访问的数据之后,贴吧都是http://tieba.baidu.com开头,把匹配得到的url进行访问。代码如下
public static Document GetHtml(String url,int page) throws IOException {
//page 页数 http://tieba.baidu.com/p/4201959797?pn=2
Document doc = Jsoup.connect("http://tieba.baidu.com"+url+"?pn="+page)
.userAgent(
"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.15)")
.timeout(3000)
.get();
try {
Thread.sleep(3000);//暂停3秒,太快会被封ip
} catch (InterruptedException e) {
e.printStackTrace();
}
return doc;
}
这样就进入帖子了,这里我们只采集用户名,信息和楼层
匹配标题,用getElementsByClass找到core_title_txt类,这个就是标题类了
Elements resultTitle=doc1.getElementsByClass("core_title_txt");//标题内容和用户名
Elements results=doc1.getElementsByClass("d_post_content_main");//内容所在的类的内容 Elements userName=doc1.getElementsByClass("icon");//用户名所在的类的内容 for (int i = 0; i < results.size(); i++) { Element result = results.get(i); Element links = result.getElementsByTag("div").get(0);//内容 Element username = userName.get(i); Elements name = username.getElementsByTag("img");//用户名 System.out.println(i+" "+" "+name.attr("username")+" "+links.text()); }这里基本上就可以爬出一个帖子页面所有我们需要的内容了,当然有些帖子太长需要翻页,那就还得找到帖子有多少页,代码如下
public static int GetPage(Document doc)好了,需要的东西都有了,设置循环就可以进行爬取了,总代吗如下
{
Elements resultPage=doc.getElementsByClass("l_reply_num");
Element result0 = resultPage.get(0);
Element result1=result0.getElementsByTag("span").get(1);
System.out.println(result1.text());
String number=result1.text();
int page = Integer.parseInt(number);//String转换成int
return page;//返回页数
}
Teste.java
package com.wuxin.main;
import java.io.IOException;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import com.wuxin.data.PostBar;
public class Teste{
public static void main(String[] args){
try {
int page=1;
Document doc=PostBar.GetHtml();//访问总贴吧
Elements baiduPost=doc.select("a.j_th_tit");//总贴吧帖子url
System.out.println(baiduPost.attr("href"));
for(Element baidupost : baiduPost)
{
page=1;
System.out.println(baidupost.attr("href"));
Document doc0=Page.GetHtml(baidupost.attr("href"),page);//帖子的html
int wu =Page.GetPage(doc0);//帖子页数
do {
Document doc1=Page.GetHtml(baidupost.attr("href"),page);
Elements resultTitle=doc1.getElementsByClass("core_title_txt");//标题
System.out.println("标题: "+resultTitle.text());
System.out.println("第"+page+"页");
Elements results=doc1.getElementsByClass("d_post_content_main");//内容
Elements userName=doc1.getElementsByClass("icon");//用户名
for (int i = 0; i < results.size(); i++)
{
Element result = results.get(i);
Element links = result.getElementsByTag("div").get(0);
Element username = userName.get(i);
Elements name = username.getElementsByTag("img");
System.out.println(i+" "+" "+name.attr("username")+" "+links.text());
}
} while ( wu!=page++);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Page.java
package com.wuxin.main;
import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class Page {
public static Document GetHtml(String url,int page) throws IOException {
Document doc = Jsoup.connect("http://tieba.baidu.com"+url+"?pn="+page)
.userAgent(
"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.15)")
.timeout(3000)
.get();
try {
Thread.sleep(3000);//暂停3秒,太快会被封ip
} catch (InterruptedException e) {
e.printStackTrace();
}
return doc;
}
public static int GetPage(Document doc)
{
Elements resultPage=doc.getElementsByClass("l_reply_num");
Element result0 = resultPage.get(0);
Element result1=result0.getElementsByTag("span").get(1);
System.out.println(result1.text());
String number=result1.text();
int page = Integer.parseInt(number);//String转换成int
return page;
}
}
PostBar.java
package com.wuxin.data;
import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
public class PostBar {
public static Document GetHtml() throws IOException
{
Document doc = Jsoup.connect("http://tieba.baidu.com/f?ie=utf-8&kw=%E9%83%91%E7%A7%80%E5%A6%8D")//想爬哪个吧就把这里的url换掉
.userAgent(
"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.15)")
.timeout(5000)
.get();
return doc;
}
}
运行结果如图所示
代码很简单,只是简单爬取了贴吧的3个属性数据,如果大家还想要爬取图片或者楼中楼之类的话自己去扩展实现吧,也不难的,也可以在这基础之上进行优化爬取或者把数据存储到数据库(听说现在大数据蛮值钱的,搞不好以后这些数据能卖钱呢哈哈哈)。
想爬取其他贴吧的话就把PostBar.java里的访问url换掉就行了,我测试了2个吧,都能爬。
PS:天冷了,人有点懒。所以这个爬虫只能爬取总吧的前50个帖子,所以想爬更多的话就参考上面翻页思路或者自己琢磨下怎么翻页吧