赞
踩
总体思路是获取网页加载完成后的html内容,解析html然后获取所需要的元素,从而获得需要的信息。
1、环境准备工作
知识上需要有基本的java和html知识;环境上需要准备java、selenium和chrome浏览器及对应的chrmoedriver(也可以使用firefox等浏览器,需要另外进行简单的配置),mac os下selenium+chrome的环境准备可以参见我的另一篇博客:http://blog.csdn.net/egg1996911/article/details/72085151。
2、分析所需要爬虫的网站的html结构
以新浪nba(http://sports.sina.com.cn/nba/)为例,我想要爬取的内容为首页的新闻信息,如下图中蓝框所框部分:
打开浏览器的开发者工具,分析所框部分的html元素:
可以发现新闻内容都在class=“item”的li元素下,这样我们就有迹可循了。
3、编写代码
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* Created by deng on 2018/3/6.
*/
public class SinaSportsSpider implements Spider {
private final static String TARGET_URL = "http://sports.sina.com.cn/nba/";
private final static String FILE_NAME = "/Users/deng/IdeaProjects/Spider/src/SinaSportsNews.txt";
public void run() throws InterruptedException {
StringBuilder allNewses = new StringBuilder();
WebDriver driver = MyWebDriver.createWebDriver();
driver.get(TARGET_URL);
WebDriver newsDriver = MyWebDriver.createWebDriver();
// 超过8秒即为超时,会抛出Exception
newsDriver.manage().timeouts().pageLoadTimeout(8, TimeUnit.SECONDS);
Document document = Jsoup.parse(driver.getPageSource());
List<Element> liTags = document.getElementsByClass("item");
for (int i = 0; i < 3; i++) {
List<Element> aTags = liTags.get(i).getElementsByTag("a");
// 遍历单条新闻
for (Element a : aTags) {
String href = a.attr("href");
// 筛选出新闻的url
if (href.contains("sports.sina.com.cn") && href.contains("shtml")) {
System.out.println(href);
allNewses.append(href + "\n");
try {
newsDriver.get(href);
} catch (Exception e) {
// 加载页面超时,执行js手动停止页面加载
((JavascriptExecutor) newsDriver).executeScript("window.stop()");
}finally {
Document newsDocument = Jsoup.parse(newsDriver.getPageSource());
String title = newsDocument.getElementsByClass("main-title").get(0).text();
Element dateAndSource = newsDocument.getElementsByClass("date-source").get(0);
String date = dateAndSource.getElementsByTag("span").get(0).text();
String source = dateAndSource.getElementsByTag("a").get(0).text();
allNewses.append(title + "\n");
allNewses.append(date + " " + source + "\n");
Element article = newsDocument.getElementById("artibody");
for (Element p : article.getElementsByTag("p")) {
allNewses.append(p.text().trim() + "\n");
}
}
}
}
}
Thread.sleep(3000);
driver.quit();
newsDriver.quit();
MyFileWriter.writeString(FILE_NAME, allNewses.toString());
}
public static void main(String[] args) {
try {
new SinaSportsSpider().run();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

4、总结
代码比较简单粗暴,有很多待改进的地方。
1) 设置8秒为超时时间的行为不够合理,比如为什么是8秒(过长浪费时间,过短会导致内容未加载完成),应该有更好的方案解决(比如使用Selenium的显示等待机制,待研究);
2) 当爬虫中间出现异常时,会导致之前已爬取到的内容丢失,同时也会导致爬虫无法继续进行下去,没有异常恢复机制等措施;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。