本文项目san-spider源码地址
https://github.com/lufei222/san-spider.git
1、爬虫基本概念
爬虫的概念 :网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。这是百度百科对爬虫的定义,其实,说简单点,爬虫就是利用写好的程序自动的提取网页的信息。
2、爬虫的分类
通用爬虫:通用爬虫是搜索引擎(Baidu、Google、Yahoo等)“抓取系统”的重要组成部分。主要目的是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份。 简单来讲就是尽可能的;把互联网上的所有的网页下载下来,放到本地服务器里形成备分,在对这些网页做相关处理(提取关键字、去掉广告),最后提供一个用户检索接口。
聚焦爬虫:聚焦爬虫是根据指定的需求抓取网络上指定的数据。例如:获取豆瓣上电影的名称和影评,而不是获取整张页面中所有的数据值。
增量式爬虫:增量式是用来检测网站数据更新的情况,且可以将网站更新的数据进行爬取。
3、爬虫的价值
抓取互联网上的数据,为我所用,有了大量的数据,就如同有了一个数据银行一样,下一步做的就是如何将这些爬取的数据产品化,商业化。
开源的爬虫框架已经很多了,有各种语言(比如:python、java)实现的,有单机的,还有大型分布式的,多达上百种,详情可见:
开源中国网络爬虫框架列表
33款可用来抓数据的开源爬虫软件工具
爬虫项目经验小结
github上有哪些优秀的java爬虫项目
我们的要求也不高:
选定好一款爬虫开源框架后,就要考虑自己的业务特点,设计自己的项目架构了,大多数用爬虫的人,基本需求其实是类似的。
最终一般的爬虫项目都是这样的操作:
将目标网站的页面尽可能快速的扒下来
然后解析出有用的内容
落地存储到db、缓存
稍微成熟爬虫开源框架基本上都已经实现了第一步 。
根据实际业务规则解析完了以后,如何落地、保持更新网站变更策略,都需要我们去考虑。
可以参考 开源网络爬虫框架应该怎么选?
考虑选型的时候主要有以下参考项:
上面说的爬虫,基本可以分3类:
Nucth:
优点:分布式抓取,存储和索引,有hadoop支持,第三方插件丰富
缺点:使用上手难,用Nutch进行爬虫的二次开发,爬虫的编写和调试所需的时间,往往是单机爬虫所需的十倍时间不止。
对于单机爬虫框架,日常开发中占用时间多的地方就是网页内容解析,所以首先要介绍下优秀的HTML网页解析器 :Jsoup和Htmlunit和神器Selenium
上面列举的单机爬虫中,Gecco基于注解方式实现,官方demo无法运行,体验太差,首先排除不考虑。
对于其他几个,功能都很丰富,且都在持续更新中。
name | Github Star | 文档丰富度 | 使用项目数 | 网络博文丰富度(10) |
---|---|---|---|---|
Crawler4j | 3.9k | 5 | 199 | 6 |
WebMagic | 9.1k | 非常齐全 | 586 | 7.5 |
WebCollector | 2.6k | 7 | 72 | 7.5 |
从以上几个指标来看,都很优秀
基于我实际项目运行对比情,WebMagic文档丰富上手快,demo项目多,所以当前日常使用WebMagic。
主要说 Python 爬虫,以Scrapy为首,对比Java主要优势在于
综上对比:
分布式爬虫Nucth有点大材小用,开发效率也不高,暂时不打算考虑。
在日常Java项目中,我会首选WebMagic,而当需要花费大量时间精力去做爬虫工作的时候,我会选择Python的Scrapy。
如何应对网站反爬虫策略?如何高效地爬大量数据?
爬虫突破封禁的6种常见方法
常见反爬虫机制与应对方法
爬虫与反爬虫的博弈
爬虫和反爬虫都是一直在进步的,下面列举一些常见的爬与反爬运用涉及的相关知识点
CSS选择器 + Xpath + 正则表达式整理
xpath表达式
Jsoup源码
WebCollector源码
接下来大篇幅主要介绍Webmagic,因为先简要介绍下其他解析器。
使HttpClient、Jsoup、Htmlunit爬取网页实例代码源码:
LagouMulSpider.java
package demo;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.util.List;
import java.util.Random;
/**
* lagou多种不同方式实现的爬虫
* 测试htmlunit、jsoup、httpclient直接爬取
*/
public class LagouMulSpider {
static Random random = new Random();
private static String LAGOU_URL = "https://www.lagou.com/zhaopin/ceo/1/?filterOption=3&sid=f1937baf1115438c9ea9aee62836a985";
public static void main(String[] args) throws IOException, InterruptedException {
//直接httpclient爬取lagou网页,会提示存在恶意访问行为被拦截,
testHttpClient();
testJsoup();
testHtmlunitLagou();
testHtmlunitBaidu();
}
private static void testJsoup() throws IOException, InterruptedException {
System.out.println("************************testJsoup************************");
for(int i=0;i<2;i++) {
Document doc = Jsoup.connect(LAGOU_URL).get();
Elements newsHeadlines = doc.select(".pager_container");
System.out.println(newsHeadlines);
Thread.sleep(200);
}
}
private static void testHttpClient() {
try {
System.out.println("************************testHttpClient************************");
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(LAGOU_URL);
CloseableHttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
String content = EntityUtils.toString(entity, "utf-8");
response.close();
Jsoup.parse(content);
Document doc = Jsoup.parse(content);
Elements elements = doc.getElementsByTag("title");
System.out.println(elements);
}catch (Exception e){
System.out.println(e.getCause());
}
}
private static BrowserVersion getRandomBrowserVersion(){
int i = random.nextInt(5);
BrowserVersion browserVersion = BrowserVersion.getDefault();
switch (i){
case 1: browserVersion = BrowserVersion.CHROME ;break;
case 2: browserVersion = BrowserVersion.FIREFOX ;break;
case 3: browserVersion = BrowserVersion.FIREFOX_68 ;break;
case 4: browserVersion = BrowserVersion.BEST_SUPPORTED ;break;
case 5: browserVersion = BrowserVersion.INTERNET_EXPLORER ;break;
default: ;
}
return browserVersion;
}
/**
* 测试循环获取lagou的页面是否也是五次限制,还是真的能像浏览器一样正常访问.发现其实是一样限流了,超过32秒才能继续访问
* @throws IOException
* @throws InterruptedException
*/
private static void testHtmlunitLagou() throws IOException, InterruptedException {
System.out.println("************************testHtmlunitLagou************************");
for(int i=0;i<2;i++){
//创建一个webclient
WebClient webClient = new WebClient(getRandomBrowserVersion());
//htmlunit 对css和javascript的支持不好,所以请关闭之
webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setCssEnabled(false);
//获取页面
HtmlPage page = webClient.getPage(LAGOU_URL);
List<Object> byXPath = page.getByXPath("//div[@class='pager_container']//text()");
System.out.println(byXPath);
//关闭webclient
webClient.close();
}
}
private static void testHtmlunitBaidu() throws IOException {
System.out.println("************************testHtmlunitBaidu************************");
String str;
//创建一个webclient
WebClient webClient = new WebClient();
//htmlunit 对css和javascript的支持不好,所以请关闭之
webClient.getOptions().setJavaScriptEnabled(false);
webClient.getOptions().setCssEnabled(false);
//获取页面
HtmlPage page = webClient.getPage("http://www.baidu.com/");
//获取页面的TITLE
str = page.getTitleText();
System.out.println(str);
webClient.close();
}
}
WebCollector解析实例
Java爬虫框架WebMagic的介绍及使用(定时任务、代理)
官方文档
Java爬虫框架WebMagic入门
1、WebMagic框架简介
PageProcessor、Scheduler、Downloader和Pipeline,对应爬虫生命周期中的处理、管理、下载和持久化等功能,都是Spider中的属性,爬虫框架通过Spider启动和管理。
2、四大组件
3、用于数据流转的对象
Request 是对URL地址的一层封装,一个Request对应一个URL地址。
Page 代表了从Downloader下载到的一个页面——可能是HTML,也可能是JSON或者其他文本格式的内容。
ResultItems 相当于一个Map,它保存PageProcessor处理的结果,供Pipeline使用。
WebMagic其他 demo
WebMagic实例 GiteeAutoLoginSpider.java
视频展示效果如下
https://share.weiyun.com/liXqrw51
https://weibo.com/tv/v/J7HTMa0Zu?fid=1034:4518366212194347
package demo;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.openqa.selenium.By;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.pipeline.ConsolePipeline;
import us.codecraft.webmagic.pipeline.FilePipeline;
import us.codecraft.webmagic.processor.PageProcessor;
/**
* gitee自动化登录获取私有项目
*/
public class GiteeAutoLoginSpider implements PageProcessor {
private static String GITEE_NAME = System.getenv("GITEE_NAME");
private static String GITEE_USERNAME = System.getenv("GITEE_USERNAME");
private static String GITEE_PASSWORD = System.getenv("GITEE_PASSWORD");
private static String GITEE_URL = "https://gitee.com/login";
private Site site = Site.me().setRetryTimes(3).setSleepTime(1000).setTimeOut(10000);
// 用来存储cookie信息
private Set<Cookie> cookies = new HashSet<>();
@Override
public Site getSite() {
// 将获取到的cookie信息添加到webmagic中
for (Cookie cookie : cookies) {
site.addCookie(cookie.getName(), cookie.getValue());
}
return site;
}
/**
* 解析网页节点具体业务逻辑
* @param page
*/
@Override
public void process(Page page) {
System.out.println("开始解析");
String tabName = page.getHtml().xpath("//a[@class='item f-bold']//allText()").get();
System.out.println(tabName);
List<String> projects = page.getHtml().xpath("//span[@class='project-title']//allText()").all();
List<String> privateProject = projects.stream().filter(x -> x.contains("san")).distinct().collect(Collectors.toList());
System.out.println(privateProject);
page.putField("gitee project ", privateProject);
}
/**
* 登录获取cookie的操作
*
* 使用selenium+chromedriver驱动完成自动登录gitee获取cookie的操作
* 对于大多数网站可以直接获得cookie
* 对于大型的验证比较多的网站,会比较麻烦,建议可以百度 或者 github参照其他项目的selenium自动登录实现
* 在自动登录实现不可行的时候,更快的方式是直接浏览器登录手动复制cookie,以便后续登录之后的操作继续正常进行
*/
public void login() {
// 登陆
System.setProperty("webdriver.chrome.driver", "D:/chromedriver/chromedriver.exe"); // 注册驱动
WebDriver driver = new ChromeDriver();
driver.get(GITEE_URL);// 打开网址
// 防止页面未能及时加载出来而设置一段时间延迟
try {
Thread.sleep(1000);
// 设置用户名密码
driver.findElement(By.id("user_login")).sendKeys(GITEE_USERNAME); // 用户名
driver.findElement(By.id("user_password")).sendKeys(GITEE_PASSWORD); // 密码
// 模拟点击
driver.findElement(By.name("commit")).click();
// 防止页面未能及时加载出来而设置一段时间延迟
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 获取cookie信息
cookies = driver.manage().getCookies();
System.out.println("cookie " + cookies);
driver.close();
}
public static void main(String[] args) {
String url = "https://gitee.com/"+GITEE_NAME+"/dashboard/projects?scope=private&&sort="; // 地址
GiteeAutoLoginSpider dome = new GiteeAutoLoginSpider();
// 登陆
dome.login();
Spider.create(dome)
.addUrl(url)
//输出内容到控制台
.addPipeline(new ConsolePipeline())
//输出内容到文件
.addPipeline(new FilePipeline("D:\\webmagic\\gitee"))
.run();
}
}
经过项目的经验时间,其实上面列举的功能都很强大,如果只是Java项目当中由于一些需求需要使用,那么其实Jsoup或者Htmlunit足矣,要有代理、多线程、去重、头部设置、自动登录等,则根据自己需要引入WebMagic或Selenium等,参照着Github上面的丰富的爬虫项目肯定能完成自己的需求。
如果你需要投入大量时间精力在爬虫上面的话,建议直接用Python的Scrapy,已有开源项目足矣让你在爬虫工作上游刃有余。
本文项目san-spider源码地址
https://github.com/lufei222/san-spider.git
参考
口罩地址Python
htmlunit 爬虫案例
实例二 htmlunit
解决htmlunit的webclient对象在多线程环境下的共享问题
高级爬虫进阶:HtmlUnit+多线线程+消息队列快速抓取大量信息数据
Java爬虫,爬取京东、天猫、淘宝、阿里巴巴、苏宁、国美、考拉电商数据
基于webmagic的爬虫项目经验小结
CSS选择器 + Xpath + 正则表达式整理
在开源中国爬虫分类的软件
雪球网的爬虫
今日头条相关的httpunit
Nutch、heritrix、crawler4j优缺点
关于webmagic的说明文档
基于Webmagic的Java爬虫(四)爬取动态列表页内容
基于webmagic的理财产品分页
java爬虫Gecco工具抓取新闻实例
爬虫京东
java爬虫事例
github上有哪些优秀的java爬虫项目
https://www.zhihu.com/question/31427895
https://www.52pojie.cn/thread-1068214-1-1.html
使用WebMagic多线程爬取图+httpClient多线程下载图片
拉勾网爬取(WebMagic+Selenium+ChromeDriver)
https://blog.csdn.net/weixin_43719622/article/details/102784141
https://github.com/Yangtze-Innovation/Search-Job-Platfom/tree/CourageHe/2-WebMagic/4-WebMagicSelenimu
第一次用webmagic写爬虫
webmagic简书
爬取动态页面模拟登录
WebMagic 实现爬虫入门教程
爬取页面需要登陆才可爬取,这种怎么解决
不能登录的常见问题1
不能登录的常见问题2
webmagic框架图
WebMagic实现分布式抓取以及断点抓取,爬虫主要运行时间消耗是请求网页时的io阻塞,所以开启多线程,让不同请求的等待同时进行,可以大大提高爬虫运行效率
多线程爬虫图
Gather Platform 聚集收集平台
基于Crawler4j + jsoup实现虫
selenium介绍
crawler4j简介
htmlunit HtmlUnit的使用
webcollector简介
Java开源爬虫框架WebCollector爬取CSDN博客
爬取微信公众号
Java开源爬虫框架WebCollector爬取搜索引擎
爬虫与反爬虫