java 中常用框架、intell idea的使用、爬虫系统

***intell idea的使用

设置mavende本地仓库:file-》settings-〉build-》build tools-〉maven-》配置maven的环境,maven home directory,user setting files,local repository

 

 

***java 中常用框架

**mycat:数据库操作;

https://www.cnblogs.com/fyy-hhzzj/p/9044775.html

mycat分布式数据库的中间件;对读写分离,分库分表支持.

mysql单表可以存储1000万条数据,超过了就要进行分库分表设计.

使用的时候需要有四个配置文件:server.xml、schema.xml、rule.xml(分片的算法)、sequence_db_conf.properties;

Mycat的默认端口是:8066

使用步骤:下载mycat、启动mycat、

 

**HBase

 

**Zookeeper分布式自增主键

 

 **Webmagic爬虫框架:http://git.oschina.net/flashsword20/webmagic

文档:http://webmagic.io/、http://webmagic.io/docs/zh

webmagic大致工作流程:请求网址-》Downloader下载网页-〉PageProcessor解析网页,解析出更多的网址-》Pipeline负责抽取结果的处理或者继续request请求,之类要Scheduler做去重管理,-〉继续Downloader下载网页,-》PageProcessor解析网页,-〉Pipeline负责抽取结果的处理.

需要使用代理ip,设置成动态的代理ip;

Selenium是一个模拟浏览器进行页面渲染的工具,WebMagic依赖Selenium进行动态页面的抓取,可以对 JavaScript 生成信息进行抽取;

chromeDriver是谷歌开发的自动化测试接口;

HttpClient是Http请求组件,Jsoup是网页解析器(内置了Http请求功能).

WebMagic使用Jsoup作为HTML解析工具,

爬虫的分类:分布式和单机,分布式主要就是apache的nutch框架,java实现,依赖hadoop运行,学习难度高,一般只用来做搜索引擎开发。

    java单机的框架有:webmagic和webcollector以及crawler4j.

    python单机的框架:scrapy和pyspider.

webmagic-selenium支持动态网页的爬取,webmagic-saxon支持X-Path和XSLT的解析.

 WebMagic的代码分为两部分:webmagic-core和webmagic-extension,WebMagic支持使用独有的注解风格编写一个爬虫,引入webmagic-extension包即可使用此功能。

 WebMagic由四个组件(Downloader、PageProcessor、Scheduler、Pipeline)构成。Spider是内部流程的核心,四大组件都是它的属性。

1.Downloader

Downloader负责从互联网上下载页面,以便后续处理。WebMagic默认使用了Apache HttpClient作为下载工具。

2.PageProcessor

PageProcessor负责解析页面,抽取有用信息,以及发现新的链接。WebMagic使用Jsoup作为HTML解析工具,并基于其开发了解析XPath的工具Xsoup。

在这四个组件中,PageProcessor对于每个站点每个页面都不一样,是需要使用者定制的部分。

3.Scheduler

Scheduler负责管理待抓取的URL,以及一些去重的工作。WebMagic默认提供了JDK的内存队列来管理URL,并用集合来进行去重。也支持使用Redis进行分布式管理。

除非项目有一些特殊的分布式需求,否则无需自己定制Scheduler。

4.Pipeline

Pipeline负责抽取结果的处理,包括计算、持久化到文件、数据库等。WebMagic默认提供了“输出到控制台”和“保存到文件”两种结果处理方案。

Pipeline定义了结果保存的方式,如果你要保存到指定数据库,则需要编写对应的Pipeline。对于一类需求一般只需编写一个Pipeline。

 ** Spider也是WebMagic操作的入口,它封装了爬虫的创建、启动、停止、多线程等功能。



 public static void main(String[] args){
//使用一个PageProcessor创建一个Spider对象
     Spider.create(new ListPageProcesser()) 

//第一个需要爬取的地址,从https://github.com/code4craft开始抓
 .addUrl("https://github.com/code4craft") 

//设置Scheduler,使用Redis来管理URL队列
 .setScheduler(new RedisScheduler("localhost")) 

//设置Pipeline,将结果以json方式保存到文件
.addPipeline(new JsonFilePipeline("D:\\data\\webmagic")) 

//开启5个线程同时执行 
.thread(5) 

//启动爬虫
 .run();

  }

WebMagic默认提供了“输出到控制台”和“保存到文件”两种结果处理方案。WebMagic用于保存结果的组件叫做Pipeline。通过“控制台输出结果”这件事也是通过一个内置的Pipeline完成的,它叫做ConsolePipeline。那么,我现在想要把结果用Json的格式保存下来,怎么做呢?我只需要将Pipeline的实现换成"JsonFilePipeline"就可以了。

.addPipeline(new FilePipeline("/data/edu1"))设置爬取结果存储形式和位置,保存位置是/data/edu1。

.addPipeline(new ConsolePipeline()) 设置爬取结果存储形式和位置,这里将结果同时输出到console页面。

.setScheduler(new FileCacheQueueScheduler()) 使用文件保存抓取的URL,可以在关闭程序并下次启动时,从之前抓取的URL继续抓取。需指定路径,会建立.urls.txt和.cursor.txt两个文件。

WebMagic里主要使用了三种抽取技术:XPath、正则表达式和CSS选择器。

 

**抽取结果的api

//获取整个html
 page.putField("download", page.getHtml().toString());
//获取第一个a链接的地址
page.putField("download", page.getHtml().links().toString());
//获取所有a链接的地址,在links后面也可以加上正则
page.putField("download", page.getHtml().links().all().toString());

//获取当前请求的url.
page.getUrl


//**正则  (https://www.runoob.com/regexp/regexp-metachar.html)
 page.putField("download", page.getHtml().regex("https://bss.csdn.net/cview/reg/.*").toString());


//***xpath  (https://www.w3school.com.cn/xpath/xpath_syntax.asp)

//获取类选择器叫lt_avatar的div
 page.putField("download", page.getHtml().xpath("//div[@class='lt_avatar']"));
//获取类选择器叫lt_avatar的div下的img
 page.putField("download", page.getHtml().xpath("//div[@class='lt_avatar']/img"));
//获取img中src属性
page.putField("download", page.getHtml().xpath("//div[@class='lt_avatar']/img/@src"));
//text()获取元素a中的文本值,在pipeline中entry.getValue()没有值
page.putField("download", page.getHtml().xpath("//div[@class='lt_avatar']/a/text()"))
//tidyText()获取元素a中的文本值,在pipeline中entry.getValue()会解析出href的链接
page.putField("download", page.getHtml().xpath("//div[@class='lt_avatar']/a/tidyText()"));


//***css,这里的lt_avatar就是属性值,格式:直接元素加属性值,子元素直接写在后面.
 page.putField("download", page.getHtml().css("div.lt_avatar a"));
//这里后面的text表示获取a链接的文本值
page.putField("download", page.getHtml().css("div.lt_avatar a","text"));
//后面的href表示获取a链接的href属性值
 page.putField("download", page.getHtml().css("div.lt_avatar a","href"));


//***选择器
 Elements mainElements = page.getHtml().getDocument()
                 .getElementsByClass("lt-dialog__title");
    	 String t=mainElements.text();
String attr= mainElements.text.attr("src");//获取元素属性值
    	 System.out.println(t);

            //获取当前元素
            String html = mainElements(0).html();
            List all = new Html(html)
                    .xpath("//div[@class=\"mod_relations\"]").links().all();
            // 加入到爬虫队列
            page.addTargetRequests(all);

**获取结果的api

get()	返回一条String类型的结果	String link= html.links().get()
toString()	功能同get(),返回一条String类型的结果	String link= html.links().toString()
all()	返回所有抽取结果	List links= html.links().all()
match()	是否有匹配结果	if (html.links().match()){ xxx; }

**site的相关配置

private String domain;//主机域名

private String  userAgent;//http协议中的UserAgent

private MapdefaultCookies =new LinkedHashMap();//默认cookie

private Mapcookies =new HashMap>();//cookie

private String charset;//编码格式

private int sleepTime =5000;//休眠时间

private int retryTimes =0;//重试时间

private int cycleRetryTimes =0;//重试此时

private int retrySleepTime =1000;//重试休眠时间

private int timeOut =5000;//默认关闭时间

private static final SetDEFAULT_STATUS_CODE_SET =new HashSet();//状态码集合

private Set acceptStatCode =DEFAULT_STATUS_CODE_SET;//默认成功的网页返回码

private Mapheaders =new HashMap();//http协议

private boolean useGzip =true;//默认使用zip解码

private boolean disableCookieManagement =false;//需不需要使用cookie管理者

***简单实例

***pom.xml



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.1.9.RELEASE
         
    
    com.easy
    webmagic
    0.0.1
    webmagic
    Demo project for Spring Boot

    
        1.8
        UTF-8
        UTF-8
        UTF-8
    

    
        
            us.codecraft
            webmagic-core
            0.7.3
            
                
                    org.slf4j
                    slf4j-log4j12
                
            
        
        
            us.codecraft
            webmagic-extension
            0.7.3
        

        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
        
            org.projectlombok
            lombok
            compile
        
    

    
        
            
                org.apache.maven.plugins
                maven-compiler-plugin
                
                    1.8
                    1.8
                
            
        
    




**
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import us.codecraft.webmagic.Spider;

@SpringBootApplication
public class WebmagicdemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(WebmagicdemoApplication.class, args);
		 //获取影片标题和页面链接
//        Spider.create(new ListPageProcesser()).addUrl("https://me.csdn.net/u011146511")
//                .addPipeline(new MyPipeline()).thread(1).run();
//
        //获取指定详情页面的影片下载地址
        Spider.create(new DetailPageProcesser()).addUrl("https://me.csdn.net/u011146511")
                .addPipeline(new MyPipeline()).thread(1).run();
	}

}


**

import org.jsoup.select.Elements;

import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;

public class DetailPageProcesser implements PageProcessor {
    private Site site = Site.me().setDomain("my.csdn.net");

    @Override
    public void process(Page page) {
    	
//        page.putField("download", page.getHtml().links().all().toString());
    	
    	//正则
//      page.putField("download", page.getHtml().regex("https://bss.csdn.net/cview/reg/.*").toString());
    	
//    	//选择器
//    	 Elements mainElements = page.getHtml().getDocument()
//                 .getElementsByClass("lt-dialog__title");
//    	 String t=mainElements.text();
//    	 System.out.println(t);
    	
    	//xpath
//    	 page.putField("download", page.getHtml().xpath("//div[@class='lt_avatar']"));
    	
    	//css
    	 page.putField("download", page.getHtml().css("div.lt_avatar a","href"));
    	 
    	 
    	 
    	
    }

    @Override
    public Site getSite() {
        return site;
    }
}

**

import lombok.extern.slf4j.Slf4j;
import us.codecraft.webmagic.ResultItems;
import us.codecraft.webmagic.Task;
import us.codecraft.webmagic.pipeline.Pipeline;

import java.util.Map;

@Slf4j
public class MyPipeline implements Pipeline {
    @Override
    public void process(ResultItems resultItems, Task task) {
        log.info("get page: " + resultItems.getRequest().getUrl());
        for (Map.Entry entry : resultItems.getAll().entrySet()) {
  /* ResultItems 保存了抽取结果,它是一个 Map 结构,    
 *在 page.putField(key,value)中保存的数据,可以通过 ResultItems.get(key)获取,这个key就是之前putFile中的key ,
 *getvalve就是解析获取的结果,这个结果就是putFile中value解析后的结果.
  */
            log.info("解析的结果"+entry.getKey() + ":\t" + entry.getValue());
        }
    }
}
除了使用  page.addTargetRequests(url或者url集合) 加入到爬虫队列.

还可以使用request模拟post请求添加到爬虫队列.
                 Request req = new Request();
                   req.setMethod(HttpConstant.Method.POST);
    	                 req.setUrl("my.csdn.net");
    	               req.setRequestBody(HttpRequestBody.json("{CategoryType: 'SiteHome', ParentCategoryId: 0, CategoryId: 808, PageIndex: " + pageNum
    	                       + ", TotalPostCount: 4000,ItemListActionName:'PostList'}", "utf-8"));
    	       page.addTargetRequest(req);

 

**WebCollector爬虫系统:https://github.com/CrawlScript/WebCollector

教程:https://www.oschina.net/p/webcollector

多种情况教程:http://datahref.com/archives/10

获取网站图片
@SpringBootApplication

//@ComponentScan("com.example.service")
public class DemoApplication {
	 
	public static void main(String[] args) {
		  Logger logger = LoggerFactory.getLogger(DemoApplication.class);
		    logger.info("Hello World");
	
		    /**
	         * ZhihuCrawler 构造器中会进行 数据初始化,这两个参数接着会传给父类
	         * super(crawlPath, autoParse);
	         * crawlPath:表示设置保存爬取记录的文件夹,本例运行之后会在应用根目录下生成一个 "crawl" 目录存放爬取信息
	         * */
		    ZhihuCrawler crawler = new ZhihuCrawler("crawl", true);
		    //设置为断点爬取,否则每次开启爬虫都会重新爬取
		    crawler.setResumable(true);
	        /**
	         * 启动爬虫,爬取的深度为4层
	         * 添加的第一层种子链接,为第1层
	         */
	        try {
				crawler.start(4);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}


	}
	
}


***
package com.example.crawler;

import java.io.File;
import java.io.IOException;

import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;

import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import cn.edu.hfut.dmic.webcollector.model.CrawlDatum;
import cn.edu.hfut.dmic.webcollector.model.CrawlDatums;
import cn.edu.hfut.dmic.webcollector.model.Page;
import cn.edu.hfut.dmic.webcollector.net.HttpRequest;
import cn.edu.hfut.dmic.webcollector.net.HttpResponse;
import cn.edu.hfut.dmic.webcollector.plugin.berkeley.BreadthCrawler;
import cn.edu.hfut.dmic.webcollector.util.FileUtils;
/**
 * BreadthCrawler 是 WebCollector 最常用的爬取器之一

 * */
public class ZhihuCrawler extends BreadthCrawler{
	 // 用于保存图片的文件夹
    File downloadDir;

    // 原子性int,用于生成图片文件名
    AtomicInteger imageId;
    private final static String downPath = "/Users/HaokeMaster/Desktop/sts/jianshuImage";
	public ZhihuCrawler(String crawlPath, boolean autoParse) {
		super(crawlPath, autoParse);
		//只有在autoParse和autoDetectImg都为true的情况下
        //爬虫才会自动解析图片链接
        setAutoParse(true);

        //如果使用默认的Requester,需要像下面这样设置一下网页大小上限
        //否则可能会获得一个不完整的页面
        //下面这行将页面大小上限设置为10M
        //getConf().setMaxReceiveSize(1024 * 1024 * 10);
		
		 /**设置爬取的网站地址
         * addSeed 表示添加种子
         * 种子链接会在爬虫启动之前加入到抓取信息中并标记为未抓取状态.这个过程称为注入*/
        //添加种子URL
        addSeed("http://www.meishij.net/");
        //限定爬取范围
        addRegex("http://www.meishij.net/.*");
        addRegex("http://images.meishij.net/.*");
        addRegex("-.*#.*");
        addRegex("-.*\\?.*");
        this.addSeed("https://www.meishij.net");
 
        /**
         * 循环添加了4个种子,其实就是分页,结果类似:
         * https://blog.github.com/page/2/
         * https://blog.github.com/page/3/
         * https://blog.github.com/page/4/
         * https://blog.github.com/page/5/
         */
//        for (int pageIndex = 2; pageIndex <= 5; pageIndex++) {
//            String seedUrl = String.format("https://blog.github.com/page/%d/", pageIndex);
//            this.addSeed(seedUrl);
//        }
 
        /**限定爬取范围  addRegex 参数为一个 url 正则表达式, 可以用于过滤不必抓取的链接,如 .js .jpg .css ... 等
         * 也可以指定抓取某些规则的链接,如下 addRegex 中会抓取 此类地址:
         * https://blog.github.com/2018-07-13-graphql-for-octokit/
         * */
//        this.addRegex("https://blog.github.com/[0-9]{4}-[0-9]{2}-[0-9]{2}-[^/]+/");
        /**
         * 过滤 jpg|png|gif 等图片地址 时:
         * this.addRegex("-.*\\.(jpg|png|gif).*");
         * 过滤 链接值为 "#" 的地址时:
         * this.addRegex("-.*#.*");
         */
 
        /**设置线程数*/
        setThreads(50);
        setTopN(100);
       
 
        /**
         * 是否进行断电爬取,默认为 false
         * setResumable(true);
         */

	}

	 /**
     * 必须重写 visit 方法,作用是:
     * 在整个抓取过程中,只要抓到符合要求的页面,webCollector 就会回调该方法,并传入一个包含了页面所有信息的 page 对象
     *
     * @param page
     * @param next
     */
    @Override
    public void visit(Page page, CrawlDatums next) {
    	 downloadDir = new File(downPath);
         if (!downloadDir.exists()) {
             downloadDir.mkdirs();
         }
         computeImageId();

        String url = page.url();
        /**如果此页面地址 确实是要求爬取网址,则进行取值
         */
//        if (page.matchUrl("http://www.meishij.net/")) {
 
            /**
             * 通过 选择器 获取页面 标题以及 正文内容
             * */
//            String title = page.select(".foot p").text();
//            Elements content = page.select("html");
            //我们需要网页中标签的属性来进行判断,只有html属性和图片属性的标签才有可能是图片标签
            String contentType = page.response().contentType();
            System.out.println("contentType:\n" + contentType);
            if (contentType == null) {
                return;
            } else if (contentType.contains("html")) {
                // 如果是网页,则抽取其中包含图片的URL,放入后续任务
            	 Elements imgs = page.select("img[src]");
                 for (Element img : imgs) {
                     String imgSrc = img.attr("abs:src");
                     next.add(imgSrc);
                	
                 }
            } else if (contentType.startsWith("image")) {
                // 如果是图片,直接下载
            	 String extensionName = contentType.split("/")[1];
                 String imageFileName = imageId.incrementAndGet() + "." + extensionName;
                 File imageFile = new File(downloadDir, imageFileName);
                 try {
                	 byte[] image = page.content();//图片数据
                     FileUtils.write(imageFile, image);
                     System.out.println("保存图片 " + page.url() + " 到 " + imageFile.getAbsolutePath());
                 } catch (IOException ex) {
                     throw new RuntimeException(ex);
                 }
      }
            
//            System.out.println("URL:\n" + url);
//            System.out.println("title:\n" + title);
//            System.out.println("content:\n" + content);
 
//        }
    }

    public void computeImageId() {
        int maxId = -1;
        for (File imageFile : downloadDir.listFiles()) {
            String fileName = imageFile.getName();
            String idStr = fileName.split("\\.")[0];
            int id = Integer.valueOf(idStr);
            if (id > maxId) {
                maxId = id;
            }
        }
        imageId = new AtomicInteger(maxId);
    }
	
//设置代理userAgent,需要重写getResponse
    @Override
    public HttpResponse getResponse(CrawlDatum crawlDatum) throws Exception {

        /* 设置代理服务器 */
        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8889));
        //HttpRequest hr = new HttpRequest(crawlDatum, proxy);
        HttpRequest hr = new HttpRequest(crawlDatum, null);
//         hr.setProxy(proxy);
        hr.setUserAgent(getusergent());
        return hr.response();
    }




    private static String[] agentarray = { "Mozilla/5.0 (compatible, MSIE 10.0, Windows NT, DigExt)",
            "Mozilla/4.0 (compatible, MSIE 7.0, Windows NT 5.1, 360SE)",
            "Mozilla/4.0 (compatible, MSIE 8.0, Windows NT 6.0, Trident/4.0)",
            "Mozilla/5.0 (compatible, MSIE 9.0, Windows NT 6.1, Trident/5.0),",
            "Opera/9.80 (Windows NT 6.1, U, en) Presto/2.8.131 Version/11.11",
            "Mozilla/4.0 (compatible, MSIE 7.0, Windows NT 5.1, TencentTraveler 4.0)",
            "Mozilla/5.0 (Windows, U, Windows NT 6.1, en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
            "Mozilla/5.0 (Macintosh, Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
            "Mozilla/5.0 (Macintosh, U, Intel Mac OS X 10_6_8, en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
            "Mozilla/5.0 (Linux, U, Android 3.0, en-us, Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13",
            "Mozilla/5.0 (iPad, U, CPU OS 4_3_3 like Mac OS X, en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5",
            "Mozilla/4.0 (compatible, MSIE 7.0, Windows NT 5.1, Trident/4.0, SE 2.X MetaSr 1.0, SE 2.X MetaSr 1.0, .NET CLR 2.0.50727, SE 2.X MetaSr 1.0)",
            "Mozilla/5.0 (iPhone, U, CPU iPhone OS 4_3_3 like Mac OS X, en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5",
            "MQQBrowser/26 Mozilla/5.0 (Linux, U, Android 2.3.7, zh-cn, MB200 Build/GRJ22, CyanogenMod-7) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1" 
            };

    public static String getusergent() {
        Random rand = new Random();
        return agentarray[rand.nextInt(agentarray.length)];

    }
    
}
	

https://blog.csdn.net/jiangsanfeng1111/article/details/52334907

爬取js相关:https://blog.csdn.net/osaymissyou0/article/details/49450209、https://blog.csdn.net/osaymissyou0/article/details/49450209

webcollector地址:https://github.com/CrawlScript/WebCollector/blob/master/README.md

你可能感兴趣的:(java)