网络爬虫爬取数据 本地数据库储存 远程api分析 模型
来源:互联网 发布:内容推荐算法的实现 编辑:程序博客网 时间:2024/06/05 05:16
序言
20161119 写
本次项目工程:
第一部分:https://github.com/RenjiaLu9527/WebMagic_test-20161119—mysq
第二部分:https://github.com/RenjiaLu9527/JFreeChart-20161119/
相关博客、论坛网站链接如下
WebMagic简单灵活的爬虫框架。http://webmagic.io
WebCollector JAVA爬虫框架 http://www.oschina.net/p/webcollector?fromerr=WSgeV8m4
给推荐几个github上优秀的java爬虫项目?【知乎】
83款 网络爬虫开源软件
利用WebMagic的Cookie机制进行页面爬取
DwyaneWade NBA球星德维恩·韦德 的新浪微博
java实现各种数据统计图(柱形图,饼图,折线图)
JFreechart 1.0.19开源包下载链接
一键将正则表达式转换为JAVA python等语言的字符串:
正则表达式测试工具/常用正则表达式/正则代码生成 - 在线工具
一个星期多一点,在众多的爬虫框架中选择了Webmagic,WebMagic简单灵活的爬虫框架。
简单易用,在这之前用的是WebCollector JAVA爬虫框架,它的模块划分弄了一天也没搞清楚,文档没有webmagic的全,上手太慢,所以放弃
webmagic是国人做的,目前我使用的功能很少,对其框架的扩展定制内容很少,感觉不出什么优点来,基本功能使用上手很快
正文
有个概念:
分布式:一个业务分拆多个子业务,部署在不同的服务器上
集群:同一个业务,部署在多个服务器上
爬虫可以做很多事,将网络上感兴趣的资源通过爬虫大规模的抓取,然后进行分析等其他操作,可以做出很多有意思的东西,比如‘舆情分析系统’‘网络环境文明用语情况分析’还可以‘爬取某个网站的图片、文字、视频’相当于一键直接下载,非常方便;
我做的这个小模型是
webmagic框架爬虫抓取某位微博用户的每条微博
下载保存本地并储存到本地数据库Mysql
调用Watson的Tone Analyzer API逐条分析本地数据库的数据并收集分析Json结果
用JAVA GUI显示情感变化趋势
四部分,
前两部分由于微博网站页面的显示方式是由 JSP 函数获取显示的,导致webmagic的xpath和css无法正常使用,还有他的正则表达式解析也不正常;最后不得不放弃这三个函数,老老实实的用java自带的正则解析函数才解析正常,
要点
1 大概了解网页的构成
2 webmagic熟悉基本用法(官网文档很详细)
3 JDBC等连接数据库的操作 和数据库的基本使用
4 正这表达式(重点!好好研究)
5 还是 get/post方法 和 Json解析
6 学会调用开源库 开源模板,比如这个折线图开源包
先分析网页的构成 然后再测试抓取是否成功。
这里我以 DwyaneWade NBA球星德维恩·韦德的微博为例 抓取
我将第一第二步建了一个工程 webmagic_test,第三第四步也建立一个工程JFreeChart;两个工程分开运行
webmagic_test工程目录如下
JFreeChart工程目录如下
笔记
webmagic框架的两个java文件SinaBlogProcessor.java****OneFilePipeline.java
代码如下:
SinaBlogProcessor.java
package main;import java.io.File;import java.io.FileNotFoundException;import java.io.UnsupportedEncodingException;import us.codecraft.webmagic.downloader.Downloader;import java.util.ArrayList;import java.util.List;import us.codecraft.webmagic.Page;import us.codecraft.webmagic.Site;import us.codecraft.webmagic.Spider;import us.codecraft.webmagic.Task;import us.codecraft.webmagic.pipeline.FilePipeline;import us.codecraft.webmagic.pipeline.Pipeline;import us.codecraft.webmagic.processor.PageProcessor;/** * @author code4crafter@gmail.com <br> */public class SinaBlogProcessor implements PageProcessor { public static String PATHNAME = "H:/php/wamp/wamp/www/_webmagicdata/weibodata_jdbc/jdbc_weibodata_page"; private static long userNum = 0; private static String userId = ""; private Site siteold = Site.me().setSleepTime(3000);// .setUserAgent( // "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like // Gecko) Chrome/45.0.2454.101 Safari/537.36"); private volatile static int maini = 0; private Site site = new Site().setRetryTimes(3).setSleepTime(2000).setTimeOut(10000) // 添加cookie之前一定要先设置主机地址,否则cookie信息不生效 .setDomain(".weibo.com") // 添加抓包获取的cookie信息(某些网站如果没有设定cookice无法访问) .addCookie("Apache", "6047605616040.527.1448080352314") /*如何添加 cookice:[http://blog.csdn.net/kingsonyoung/article/details/51753639] */ // 添加请求头,有些网站会根据请求头判断该请求是由浏览器发起还是由爬虫发起的 .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.245") .addHeader("Accept", "*/*").addHeader("Accept-Encoding", "gzip, deflate, sdch") .addHeader("Accept-Language", "zh-CN,zh;q=0.8").addHeader("Connection", "keep-alive").addHeader("Referer", "http://weibo.com/p/1003062264358493/home?is_search=0&visible=0&is_all=1&is_tag=0&profile_ftype=1&page=1#feedtop"); @Override public void process(Page page) { String str = "" + page.getUrl().toString(); // System.out.println("#1"); if (str.indexOf("#feedtop") >= 0) { // System.out.println("#2"); if (page.getHtml().toString().indexOf("抱歉,你访问的页面地址有误,或者该页面不存在") < 0 && page.getHtml().toString().indexOf("请检查输入的网址是否正确") < 0 && page.getHtml().toString().indexOf("网络繁忙") < 0 && page.getHtml().toString().indexOf("请稍后再试") < 0) { // System.out.println("#3"); str = str.substring(0, str.indexOf("#feedtop")); str = str.substring(str.indexOf("&page=") + 6, str.length()); int cnt = 0; int pagenum = Integer.parseInt(str); System.out.println("pagenum=" + pagenum); // 获取页数 String xialaURL1 = "http://weibo.com/p/aj/v6/mblog/mbloglist?ajwvr=6&domain=100505&is_search=0&visible=0&is_all=1&is_tag=0&profile_ftype=1" + "&page=" + pagenum + "&pagebar=0" + "&pl_name=Pl_Official_MyProfileFeed__23&id=" + userId + "&script_uri=/p/" + userId + "/home&feed_type=0" + "&pre_page=" + pagenum + "&domain_op=100505&__rnd=1479123380183"; String xialaURL2 = "http://weibo.com/p/aj/v6/mblog/mbloglist?ajwvr=6&domain=100505&is_search=0&visible=0&is_all=1&is_tag=0&profile_ftype=1" + "&page=" + pagenum + "&pagebar=1" + "&pl_name=Pl_Official_MyProfileFeed__23&id=" + userId + "&script_uri=/p/" + userId + "/home&feed_type=0" + "&pre_page=" + pagenum + "&domain_op=100505&__rnd=1479123380183"; List<String> listurl = new ArrayList<String>(); listurl.add(xialaURL1); listurl.add(xialaURL2); page.addTargetRequests(listurl); page.putField("[Chushiyemian]", page.getHtml()); } else { System.out.println("userId=" + userId + "页面不存在 404"); // userId++; maini = -1; } } else { // 两个下拉刷新页面 page.putField("[Xialashuaxin]", page.getJson()); if (page.getJson().toString().indexOf("WB_feed_detail clearfix") < 0) { maini = -1; System.out.println("userId=" + userId + "到达最后一页"); } } } @Override public Site getSite() { return site; } public static void main(String[] args) { // http://weibo.com/p/1005055317970558/home? // http://weibo.com/kevindurant?is_search=0&visible=0&is_all=1&is_tag=0&profile_ftype=1&page=2#feedtop // http://weibo.com/p/1003061735538085/home?from=page_100306_profile&wvr=6&mod=data&is_all=1#place for (userNum = 93; userNum < 99; userNum++) { userId = "10030622643584" + userNum; PATHNAME = "H:/php/wamp/wamp/www/_webmagicdata/weibodata_jdbc/" + userId + "jdbc_weibodata_page"; OneFilePipeline.cnt = 0;// 置0 String pageURLs = "http://weibo.com/p/" + userId + "/home?is_search=0&visible=0&is_all=1&is_tag=0&profile_ftype=1&page=";// 1#feedtop"; String pageURLe = "#feedtop"; String xialaPagebars = ""; for (maini = 1; maini <= 999 && maini > 0; maini++) { try { Spider.create(new SinaBlogProcessor()) // .addUrl("http://weibo.com/languageexchange?refer_flag=1001030201_&is_all=1") // .addPipeline(new // FilePipeline("H:/php/wamp/wamp/www/_webmagicdata")) .addPipeline(new OneFilePipeline(PATHNAME)).addUrl(pageURLs + maini + pageURLe).thread(50) .run(); } catch (FileNotFoundException | UnsupportedEncodingException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } System.out.println("userId=" + userId + "处理完毕/n传送至watson分析并返回显示"); } } // @Override // public void process(ResultItems arg0, Task arg1) { // // TODO 自动生成的方法存根 // System.out.println("process 2参数函数"+arg0.get("content1")); // // }1005053610038332}
注意添加 cookice才能正常访问微博,每个人的不同,此处不贴出来了
OneFilePipeline.java
package main;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import us.codecraft.webmagic.ResultItems;import us.codecraft.webmagic.Task;import us.codecraft.webmagic.pipeline.Pipeline;import us.codecraft.webmagic.utils.FilePersistentBase;import utils.Jdbc;import java.io.*;import java.util.Map;/** * @author code4crafer@gmail.com */public class OneFilePipeline extends FilePersistentBase implements Pipeline { public static int cnt = 0; private Logger logger = LoggerFactory.getLogger(getClass()); private PrintWriter printWriter; /** * create a FilePipeline with default path"/data/webmagic/" */ public OneFilePipeline() throws FileNotFoundException, UnsupportedEncodingException { this("/data/webmagic/"); // this("H:\php\wamp\wamp\www/_webmagicdata/"); } public OneFilePipeline(String path) throws FileNotFoundException, UnsupportedEncodingException { setPath(path); printWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(getFile(path)), "UTF-8")); } @Override public synchronized void process(ResultItems resultItems, Task task) { printWriter.println("url:\t" + resultItems.getRequest().getUrl()); for (Map.Entry<String, Object> entry : resultItems.getAll().entrySet()) { if (entry.getValue() instanceof Iterable) { Iterable value = (Iterable) entry.getValue(); printWriter.println(entry.getKey() + ":"); for (Object o : value) { printWriter.println(o); } } else { new Jdbc(); printWriter.println(entry.getKey() + ":\t" + entry.getValue()); // 先保存 再处理本地 Jdbc.saveToMysql(Jdbc.parseData(entry.getValue())); } } printWriter.flush(); } @Override public java.io.File getFile(java.lang.String fullName) { cnt++; System.out.println("fullname=" + fullName + cnt); return new File(fullName + cnt); }}
模块划分很清楚,不多说
一段很长的正则:
//////////////////////////////////////////////////////////////////////
1 获取 正常微博文字
网页代码
<div class=\"WB_text W_f14\" node-type=\"feed_list_content\" nick-name=\"DwyaneWade\">\n Game day! - 比赛日! <\/div>
正则表达式
(?<=(<div\Wclass=\\"WB_text\WW_f14\\"\Wnode-type=\\"feed_list_content\\"\Wnick-name=\\"\w+\\">\\n)).*?(?=<(\\\/div>))
2 转发别人的微博时,没有nick-name=\”DwyaneWade\”
网页代码
<div class=\"WB_text W_f14\" node-type=\"feed_list_content\" >\n Single Days, end today. 脱单,就在今天。<a target=\"_blank\" render=\"ext\" suda-uatrack=\"key=topic_click&value=click_topic\" class=\"a_topic\" extra-data=\"type=topic\" href="http://weibo.com/p/1003062264358493/\""http:\/\/huati.weibo.com\/k\/%E5%93%88%E5%95%A4%E8%81%94%E7%9B%9F?from=501\">#哈啤联盟#<\/a> <\/div>\n
正则表达式
(?<=(<div\Wclass=\\"WB_text\WW_f14\\"\Wnode-type=\\"feed_list_content\\"\W((>\\\w)|(.{10}\\"\w{0,50}\\">\\n)))).*?(?=<(\\\/div>))//////////////////////////////////////////////
Java String表示
"(?<=(<div\\Wclass=\\\\\"WB_text\\WW_f14\\\\\"\\Wnode-type=\\\\\"feed_list_content\\\\\"\\W((>\\\\\\w)|(.{10}\\\\\"\\w{0,50}\\\\\">\\\\n)))).*?(?=<(\\\\\\/div>))"
这么长的正则效率可能略低,但提升了代码整洁度,而且由于xpath css无法使用,没办法的办法
注意
log4j.properties文件,webmagic调用了什么必须有这个文件包含才能显示log日志
# Configure logging for testing: optionally with log filelog4j.rootLogger=WARN, stdout# log4j.rootLogger=WARN, stdout, logfilelog4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%nlog4j.appender.logfile=org.apache.log4j.FileAppenderlog4j.appender.logfile.File=target/spring.loglog4j.appender.logfile.layout=org.apache.log4j.PatternLayoutlog4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
end
略累
睡觉
20161119JJ401 16:24
- 网络爬虫爬取数据 本地数据库储存 远程api分析 模型
- Python爬虫-利用百度地图API接口爬取数据并保存至MySQL数据库
- Android 数据储存的方式之本地数据库储存
- 《网络爬虫-Python和数据分析》数据库建库建表问题
- C#网络爬虫(爬取表格数据)
- 利用python网络爬虫爬取赶集网数据
- python3网络爬虫爬取天气网空气质量数据
- 基于java的网络爬虫框架(实现京东数据的爬取,并将插入数据库)
- 基于java的网络爬虫框架(实现京东数据的爬取,并将插入数据库)
- 转载:基于java的网络爬虫框架(实现京东数据的爬取,并将插入数据库)
- 基于java的网络爬虫框架(实现京东数据的爬取,并将插入数据库)
- php爬虫:知乎用户数据爬取和分析
- 网络爬虫---2.数据分析
- Python3 大型网络爬虫实战 004 — scrapy 大型静态商城网站爬虫项目编写及数据写入数据库实战 — 实战:爬取淘宝
- 爬虫实战爬取数据
- python爬虫爬取ithome的新闻存储到本地数据库
- 取远程oracle数据库的数据
- 【网络爬虫】数据采集——将html的数据分析保存到数据库
- Ubuntu 双系统修改默认启动项
- Android相关的开源库
- 矩阵的物理意义(三)
- Elementary OS 0.4简体中文
- 2016年度csdn排名第一 何方神圣 竟然是搞ios的
- 网络爬虫爬取数据 本地数据库储存 远程api分析 模型
- vim插件vundle
- 图片的放大和缩小(不失帧)
- WebService之初体验
- 修改sql数据库默认端口(原1433端口)
- 改变态度,就能改变你的高度
- C语言中的一些关键字(十四)
- ATOM编辑器
- OfType的用法