JSoup 初体验:使用JSoup下载 Leetcode 题目

有时候会面临一段没有网络的时间,尽量利用时间准备把 LeetCode 的题目都下载到电脑上,需要用到一个小爬虫。

JSoup 早就听说过,但一直没有正式使用过(本来 Java 就用的少),但 JSoup 是个非常好用的 DOM 处理工具,因此这次使用一番。
首先看到 LeetCode 页面,关键元素大概如下

<tr>
<td>
<span class="None"> </span>
</td>
<td>173</td>
<td>
<a href="/problems/binary-search-tree-iterator/">Binary Search Tree Iterator</a>
</td>
<td>28.7%</td>
<td value='2'>Medium</td>
</tr>


这个 table-row 节点就是每道题的题目以及链接,而每个链接的 <a> 标签也在 <td> 中,

<td>
<a href="/problems/binary-search-tree-iterator/">Binary Search Tree Iterator</a>
</td>


因此首先直接选取 <td>

   Document doc = Jsoup. connect(url).get();
   Elements links = doc.select( "td" );

至于为什么不直接选取<a>节点原因有二

  1. 页面内有很多非题目的<a>链接,而只有在<td>下的才是题目对应链接
  2. 因为一个特殊的原因必须要把<td>选出来,原因如下:

观察 LeetCode 列表会发现其实有两种情况

170 后面带有一个书的标签,意味着这一条其实不是一个oj题目,点进去后会跳转到其他页面。从后面的结果可以看到这种点进去又跳转其实会让程序阻塞。而观察改节点会发现是这样的

<td>
<a href="/problems/two-sum-ii-input-array-is-sorted/">Two Sum II - Input array is sorted</a>
<i class="fa fa-book"></i>
</td>


注意到这个节点与普通题不同,多出了一个放书籍图标的<i>标签,这种节点不需要。除此之外,子节点中不包含<a>节点的也不能要。排除这两种节点后就可以选取了

for(Element link : links){
	if(!link.select("i").isEmpty() || 
		link.select("a").isEmpty()) //存在<i>或不存在<a>
		continue;

	Element aTag = (link.select("a")).first(); //只有一个,直接第一个
	String linkHref = aTag.attr("href");
	System.out.println("Get "+linkHref);
	MainApp.funcList.add(linkHref); //funcList 存的是所有oj题目的地址
}

如果答应出来,获得的地址是这样的(从上面的td节点也可以看出)

Get /problems/factorial-trailing-zeroes/
Get /problems/excel-sheet-column-number/
Get /problems/majority-element/

存的是相对路径。因此进入下载题目时,不要忘记加上前缀。题目下载后就可以存到本地啦。代码如下

FileOutputStream outFile=new FileOutputStream("LeetCode.txt"); 
int k = 0;
while(!MainApp.funcList.isEmpty()){	
	url = MainApp.funcList.remove();			
	doc = Jsoup.connect("https://oj.leetcode.com"+url).get();
	Element title = doc.select(".question-title h3").first();
	Element content = doc.select(".question-content").first();

	outFile.write((k+++".["+title.text()+"]\r\n").getBytes());
	outFile.write((content.text()+"\r\n\r\n").getBytes());

}

这样一来一个单线程的下载爬虫就完成了。改成多线程主要需要给 funclist 以及输出流或者目标文件加锁,就不赘述了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值