java爬虫之爬百度贴吧

时间:2021-07-25 16:58:10

java要期末考试了,老师竟然说不考试卷,要我们写程序来打分......我没有一点点防备... 

言归正传,我准备写一个百度贴吧爬虫给他,为了方便,使用jsoup来进行解析爬取。

用我们学校贴吧进行试验(桂林理工大学吧),这个只是个简单的试验品,不喜勿喷。

使用jsoup来进行解析爬取。

  1. Document doc = Jsoup.connect("http://tieba.baidu.com/f?ie=utf-8&kw=%E9%83%91%E7%A7%80%E5%A6%8D")//桂工吧网址    
  2.   .userAgent(                          "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.15)")  
  3.  .timeout(3000)           // 设置连接超时时间  
  4.  .get();                 // 使用 GET 方法访问 URL 

用Chrome浏览器打开桂工吧官网,按下F12键,搜索一个帖子,如图所示

java爬虫之爬百度贴吧

<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"));

输出如下(其实匹配了所有的出来,我这里只输出一个)

java爬虫之爬百度贴吧


得到访问的数据之后,贴吧都是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;

}
}

运行结果如图所示
java爬虫之爬百度贴吧

代码很简单,只是简单爬取了贴吧的3个属性数据,如果大家还想要爬取图片或者楼中楼之类的话自己去扩展实现吧,也不难的,也可以在这基础之上进行优化爬取或者把数据存储到数据库(听说现在大数据蛮值钱的,搞不好以后这些数据能卖钱呢哈哈哈)。

想爬取其他贴吧的话就把PostBar.java里的访问url换掉就行了,我测试了2个吧,都能爬。

PS:天冷了,人有点懒。所以这个爬虫只能爬取总吧的前50个帖子,所以想爬更多的话就参考上面翻页思路或者自己琢磨下怎么翻页吧

源码下载