分类目录归档:数据挖掘

对豆瓣电影的一些可视化分析|movie.douban.com data visualization

 

最近发现之前玩scrapy的时候写过一个豆瓣电影的爬虫https://github.com/DormyMo/movieman/tree/master/crawler,一直没用起来,最近正值片慌,就想爬点数据,挖下冷门的好电影,顺便做些分析,感觉豆瓣的电影数量还是不够多,早期的信息也不是很规范,不过结果还是有点意思的,下次有时间爬下imdb看看。

数据截至:2015-08-01
豆瓣历年影片数量

继续阅读

使用scrapy满足各种爬虫需求

玩爬虫也有很长一段时间了,一直没做一个记录,经常在同一个坑中跌倒,做个记录吧。

1.ImportError: Error loading object ‘scrapy.core.downloader.handlers.s3.S3DownloadHandler’: No module named win32api

安装pywin32 : http://sourceforge.net/projects/pywin32/

2.新版本(1.0+)如果spider再继承于scrapy.spider 不会执行rules,被这坑了好久,果断看了官方文档,发现变动还挺大的,几个包都变了

from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
spider也得继承于CrawlSpider,如果不重载parse,会自动根据rules抓取

3.初始化爬虫用start_url不能满足需求,需要配置Request
重载函数

def start_requests(self):yield request

4.需要在middleware或parse的时候复用request并更改url

request.replace(url = new_url)

5.需要得到配置文件或更改爬虫配置
重载函数,cls 为当前类,若是自己写的扩展需要在settings.py中声明

@classmethod
def from_crawler(cls, crawler, *args, **kwargs):return cls(*args, **kwargs)

6.得到当前spider配置文件

from scrapy.utils import project
self.settings = project.get_project_settings()

7.获取crawler状态信息

crawler.stats.get_stats()

8.随机变换代理及useragent
定义自己的middleware,设置request.meta的保留字段proxy
useragent 为设置reques.headers
返回None,继续处理此request

def process_request(self,request,spider):
    request.meta['proxy'] ="http://127.0.0.1:8888"
    request.headers.setdefault('User-Agent', ua)

9.部署scrapyd,需要创建配置文件 /etc/scrapyd/scrapyd.conf

[scrapyd]
eggs_dir    = {your dir}/eggs
logs_dir    = {your dir}/logs
items_dir   = {your dir}/items
jobs_to_keep = 100
dbs_dir     ={your dir}/dbs
max_proc    = 0
max_proc_per_cpu = 4
finished_to_keep = 100
poll_interval = 10
http_port   = 6800
debug       = on
runner      = scrapyd.runner
application = scrapyd.app.application
launcher    = scrapyd.launcher.Launcher

[services]
schedule.json     = scrapyd.webservice.Schedule
cancel.json       = scrapyd.webservice.Cancel
addversion.json   = scrapyd.webservice.AddVersion
listprojects.json = scrapyd.webservice.ListProjects
listversions.json = scrapyd.webservice.ListVersions
listspiders.json  = scrapyd.webservice.ListSpiders
delproject.json   = scrapyd.webservice.DeleteProject
delversion.json   = scrapyd.webservice.DeleteVersion
listjobs.json     = scrapyd.webservice.ListJobs
daemonstatus.json = scrapyd.webservice.DaemonStatus

10.使用scrapyd运行爬虫,出错
scrapyd CRITICAL: Unhandled error in Deferred:

'scrapy.telnet.TelnetConsole': None,
'scrapy.extensions.feedexport.FeedExporter': None,

使用chrome调试xpath

相信玩过爬虫的都知道一些库,如lxml(python),可以使用xpath方便地对HTML进行提取,但当真正用的时候,问题就来了,想找到一个元素往往要调试好几遍,而且得先code,下面提供了几个工具及如何用chrome进行xpath test

1.XPath Helper

https://chrome.google.com/webstore/detail/xpath-helper/hgimnogjllphhhkhlmebbmlgjoejdpjl

1. Open a new tab and navigate to your favorite webpage.
2. Hit Ctrl-Shift-X to open the XPath Helper console.
3. Hold down Shift as you mouse over elements on the page. The query box will continuously update to show the full XPath query for the element below the mouse pointer. The results box to its right will show the evaluated results for the query.
4. If desired, edit the XPath query directly in the console. The results box will immediately reflect any changes.
5. Hit Ctrl-Shift-X again to close the console.

2.Xpath Finder – xpath查找助手

https://chrome.google.com/webstore/detail/xpath-finder/ijaobnmmgonppmablhldddpfmgpklbfh/related

在chrome开发者工具里增加一个面板,帮助你快速查找匹配XPATH表达式的元素。

1. 匹配的节点会用红色边框突出显示。
2. 在结果列表里可以直接inspect对应节点。
3. 记录XPATH查找历史,方便查看历史。

3.chrome console

F12->$x(“//title”)

[<title>Online Tools for Software Developers (Free)</title>]

目前互联网上公布出来的正文提取算法

目前互联网上公布出来的正文提取算法,大家可以综合比较下,一起来测试下哪个更好用。 词网–北京词网科技有限公司http://demo.cikuu.com/cgi-bin/cgi-contex 猎兔网页正文提取 http://www.lietu.com/extract/ PHP版网页正文提取http://www.woniu.us/get_content_demo/ 网页正文提取分析(DEMO) http://61.128.196.27/txt 个人认为http://61.128.196.27/txt 这个提取最牛,基本上无论什么页面都能提取出来,而且能有效的保持原文风格、图片、链接。http://code.google.com/p/joyhtml/
看看这个效果不错
http://www.likeshow.net/article.asp?id=92
我一年前写的玩意 虽然不完善 但尚可用之在新闻和BLOG 论坛提取上 提取的正文对于BLOG和BBS包含评论及回复 具体原理也写很清楚了
如题,想从html源码中提取正文内容,<P></P>之间的内容,但是<P>的写法不规则。除了正则表达式的方法,还有其它的提取方法吗?谢谢!
最新下载
在线演示和最新下载:
http://www.shoula.net/ParseContenthttp://www.pudn.com/downloads152/sourcecode/internet/search_engine/detail668443.html

Google Code开源网页正文提取cx-extractor2010-05-19 12:31基于行块分布函数的通用网页正文抽取:线性时间、不建DOM树、与HTML标签无关
简述:
对于Web信息检索来说,网页正文抽取是后续处理的关键。虽然使用正则表达式可以准确的抽取某一固定格式的页面,但面对形形色色的HTML,使用规则处理难免捉襟见肘。能不能高效、准确的将一个页面的正文抽取出来,并做到在大规模网页范围内通用,这是一个直接关系上层应用的难题。
作者提出了《基于行块分布函数的通用网页正文抽取算法》,首次将网页正文抽取问题转化为求页面的行块分布函数,这种方法不用建立Dom树,不被病态HTML所累(事实上与HTML标签完全无关)。通过在线性时间内建立的行块分布函数图,直接准确定位网页正文。同时采用了统计与规则相结合的方法来处理通用性问题。作者相信简单的事情总应该用最简单的办法来解决这一亘古不变的道理。整个算法实现不足百行代码。但量不在多,在法。
项目网址:http://code.google.com/p/cx-extractor/
算法描述:基于行块分布函数的网页正文抽取算法.pdf
欢迎大家提出意见~

http://www.ngiv.cn/post/204.html
VIPS算法对搜索引擎的意义
http://blog.csdn.net/tingya/archive/2006/02/18/601954.aspx

基于视觉的Web页面分页算法VIPS的实现源代码下载
http://blog.csdn.net/tingya/archive/2006/04/28/694651.aspx
作者信息:飞跃,javascript教程-技术之家博客的博主

http://www.madcn.net/?p=791

我这里有个开源的项目,还不错,你上googlecode搜索joyhtml。
http://gfnpad.blogspot.com/2009/11/blog-post.html
下面几个是一些开源的程序:
1.一个python的基于文本密度的程序:
http://ai-depot.com/articles/the-easy-way-to-extract-useful-text-from-arbitrary-html/
ps:里面有bug,要稍加改动。 另外,对于没有对html注释部分进行处理
2.Java 开源项目: Gate
http://gate.ac.uk/

其实可以利用Dhmtl对象进行编程分析,已获得所要的数据文件,详细请看我的程序
http://www.vbgood.com/thread-94788-1-1.html
http://download.csdn.net/source/568439

一.标题块
l 分块节点:td,div,h,span
l 一般位于Head/Title的位置
l 当前单元含有<h1>-<h3>,<b>,<i>,<strong>等标签
l 样式,一般class包含title,head等字符
l 文字长度,一般大于3个字符,小于35个字符

二.发表时间块
l 分块节点:td,div, span
l 文字长度,一般小于50个字符
l 包含日期格式(2010-08-09)的字符串
l 包含以下关键字:来源,发表

三.主题块
l 分块节点:td,div
l HTML网页中有一些特殊标签,通常只出现在网页主题块中,如<P><BR>等。因此,主题块中往往包含着特殊标签。
l 主题块内容含有较多的句子,因此具有较多逗号、句号等标点符号(>5)。
l 若从信息量角度考虑,主题块一般是含有较多文字信息。
l 主题块的 标签密度=1000*标签数/文字数 应在小于一个范围。
l 主题块的 文本密度=len(文本)/len(HTML代码) 较大
l 不应该包含 “上一篇”,“下一篇”
l 包含以下字符串的内容块,判定为包含版权信息,需减权:“ICP备04000001号”,“版权所有”,“Copyright”
l 主题块序号在标题块之下
l 主题块序号在发表时间块之下
l 主题块序号在相关链接块之上

四.相关链接块
l 分块节点:td,div
l 文字应为“相关链接”、“相关新闻”、“相关报道”等敏感词,且连接比例很高。
l 链接数小于20

实现:
根据以上信息块特征,采用特征提权算法,C#(3.5)编程实现,命名为QD正文提取组件。经测试,对Html格式规范的以文字为主的内容页,正确提取率在85%以上,各大门户的新闻页面在95%以上。 例子下载(需要安装Microsoft .NET Framework 3.5)

注:QD正文提取组件 不开源,需要源码的朋友可选择付费获取。

这时挑选出的正文一般也就是到位了,但是问题是很可能在头尾残留了一些块广告。我认为这些块广告与正文中广告有很大的不同。这些广告的马脚就是其父节点,它们的父节点要么也包含了正文所在区域,也就是和正文平级,要么本身就是正文所在区域的一个子节点,很难是正文节点本身的。那么对疑似正文节点进行一次扫描,剔除那些父节点文字内容过大(包含了广告以及正文,即和正文平级)的块,也剔除那些父节点文字内容过小的块。
经过这样的处理,得到的内容基本上就是我们需要的正文了。下面就是要提取标题。
在代表整个网页的document中扫描一次,寻找那些有font字体的,strong的,h1的,title的节点,提取他们的信息。然后将得到的文字内容分词,查验分出来的词有多少是被正文包含的,包含最多的一半就是标题。但是这里要注意,有时候找到的节点本身是正文节点的子节点,那么无论怎么分,分出来都是完全包含的,所以要剔除那些本身是正文一部分的疑似标题。这样做对大部分网页也是有效了,但是对仅有的标题就在正文节点里的那些页面,目前为止我还没有特别好的想法。
这些日子也研究了一些别人的论文,有很多思想都非常好,也有很多人想到用马尔科夫,人工神经来训练。也许以后我会考虑用用看吧。现在这样也还可以,呵呵。
?
这个算法我也写了一下,不过是用C++写的。
我不太懂楼上讨论的分页是什么意思,我通过分析dom树然后用文中提到的规则进行dom结点处理以及后续的处理。
我主要是想把网页中的内容按网页框架分开,把正文部分合在一起,然后用贝叶斯决策计算正文特征支持率
提取网页内容。
现在VIPS基本写完。
但是却也发现了些问题,
比如说有些结点的坐标提取出来会有提取不出分隔条,这是因为有少数坐标有些重叠。这里涉及到一个坐标的确定问题。
然后是结点分割规则问题,现在的页面是大部分是通过DIV来组织页面。而VIPS似乎更合适TABLE组织的页面,我试过用TABLE组织的页面,分得相当不错。
另外,TINYA上面的翻译似乎改了些规则,还有部分翻译不是很准确。比如虚拟文本的定义部分与原文有些出入,不知道TINYA有没有注意到。
最后,很感谢TINYA 对这个算法的介绍。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/tingya/archive/2006/02/18/601836.aspx

中科院分词ICTCLAS5.0 配置错误处理

这个分词器调起来确实让人崩溃,今天想要把包名和dll文件换个路径,结果总是出现这样的问题:
Exception in thread “main” java.lang.UnsatisfiedLinkError: ictclas.NLPIR.NLPIR_Init([BI)Z

各种debug无果,后来发现包名改回kevin.zhang之后程序就好了。。大概是知识产权问题吧~下面转的是一个人总结的别的问题,希望大家少在调试工具上花费太多时间。
错误一:

配置路径如下:

运行ParagraphTest.java出现如下错误

Exception in thread “main” java.lang.UnsatisfiedLinkError: cn.yh.split.ICTCLAS50.ICTCLAS_Init([B)Z

at cn.yh.split.ICTCLAS50.ICTCLAS_Init(Native Method)

at cn.yh.split.Test.main(Test.java:19)

解决办法:

最开始尝试了很多方便,比如修改classpath,修改usr_path等,仍然会报错。后来将ICTCLAS50.java放在他给的例子里面有个包 ICTCLAS.I3S.AC下,结果运行正确。可能是开发ICTCLAS50为了保护版权考虑,如果不在package ICTCLAS.I3S.AC下就会报错。

错误二:

配置文件太多,包括Data和ICTCLAS50.dll等,我想把它放在一个特定的文件夹如ICTCLAS路径下。配置路径如下:

运行ParagraphTest.java出现如下错误

Exception in thread “main” java.lang.UnsatisfiedLinkError: no ICTCLAS50 in java.library.path

at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1709)

at java.lang.Runtime.loadLibrary0(Runtime.java:823)

at java.lang.System.loadLibrary(System.java:1030)

at ICTCLAS.I3S.AC.ICTCLAS50.<clinit>(ICTCLAS50.java:9)

at cn.yh.split.ParagraphTest.main(ParagraphTest.java:9)

解决办法:

很明显,这是由于java.library.path不正确,只需要将导入dll时使用load导入绝对路径即可。修改ICTCLAS50.java里面的System.loadLibrary(“ICTCLAS50”)为 System.load(new File(“”).getAbsolutePath()+”\\ICTCLASConf\\ICTCLAS50.dll”);

修改后运行又出现以下错误:

Init Fail!

Cannot Open Configure file .\Configure.xml

有错误可知,是由于找不到.\Configure.xml文件,需要将配置文件根目录设置为new File(“”).getAbsolutePath()+”\\ICTCLASConf”。在初始化ICTCLAS_Init时,将new File(“”).getAbsolutePath()+”\\ICTCLASConf”.getBytes(“GB2312”)作为参数传递就可以正确运行了。

错误三:

若修改后运行仍然出现错误:

Init Fail!

刷新项目,发现根目录多了一个ICTCLAS.log的文件,打开文件内容,能够得到错误信息:

Default Path : .

start lic check.

License file .\user.lic can not open!

表示还需要user.lic也再根目录下面。将user.lic一道根目录下。

修改后运行在此出现错误:

Init Fail!

重新打开ICTCLAS.log文件,得到错误信息:

Default Path : .

start lic check.

License succeed!Failed to open .\Data\character.idx

Cannot open file .\Data\character.idx.

则表示没有找到Data文件夹,由于我们将Data放在了ICTCLASConf目录,故需要设置Configure.xml的<DataPath>Data</DataPath>//Data文件夹路径一项为指定目录。

百度搜索结果链接转实际链接

转自:http://enenba.com/?post=237

好像从9-1开始,百度搜索结果网址的链接又开始变成这样了,”link?url=…….”,是老长老长的。自己官方SEO手册说要简短URL,什么不超过128个字符。都是浮云,看这下面一个搜索结果
我的“enenba”的搜索结果(2012-9-3)第一个网址就是

'http://www.baidu.com/link?url=ab848a4ebf3b154d5a26b46af889a39ac4eed0923116bcf0318bb786a19e417e714ea3b262d4ef8546b80f8d6cffdd1552a3595fad2084b2b04cf1a10c36485f8a3f73ced8eee0c4f9284ad8daefcb15794a404724dc8678af321201bce1cf69814e1920005bc796e241dcc9c45664d62bb227b184af812305040ecc1bab45fff26deb422fc77779a618a28d269f82c2a58db607e54d3abcff2e6a43376ae429f1088b77dbde4b1348c11ea7c7e88ec03ce7484d89fe244390e628bc04b824e78dc62f0d12df46f100fcd70a1cc2783360150eaee4b9b6928700cb776e5b84abc69565c04e97800c615c84e640fb7b971cdd88ca6478f8d07a28058dd50ab7879c3340ad84d7c6e9fb779710a060cc6d26cbdb0ab7e7f8b70ffd77e025470569f0be3580991c83d6db4b78c2f7e75713c73c8683feebeded81088e8706b23c64747f20084e726f0de41906254a0f0983430a990861e8ddd9fd1d832b872aebac5573358cc3c0659257bfcf54763ec1c5ecff3b3fbd1d4c'

目前还是找不到什么规律的,不过想要得到跳转后的网址也不难。
我又挖了以前的文章了:

 

 

<?php
/*
	getrealurl 获取301、302重定向后的URL地址  by enenba.com
	@param str $url 查询
	$return str  定向后的url的真实url
 */
function getrealurl($url){
	$header = get_headers($url,1);
	if (strpos($header[0],'301') || strpos($header[0],'302')) {
		if(is_array($header['Location'])) {
			return $header['Location'][count($header['Location'])-1];
		}else{
			return $header['Location'];
		}
	}else {
		return $url;
	}
}


//恶心的一长串字符
$url = 'http://www.baidu.com/link?url=ab848a4ebf3b154d5a26b46af889a39ac4eed0923116bcf0318bb786a19e417e714ea3b262d4ef8546b80f8d6cffdd1552a3595fad2084b2b04cf1a10c36485f8a3f73ced8eee0c4f9284ad8daefcb15794a404724dc8678af321201bce1cf69814e1920005bc796e241dcc9c45664d62bb227b184af812305040ecc1bab45fff26deb422fc77779a618a28d269f82c2a58db607e54d3abcff2e6a43376ae429f1088b77dbde4b1348c11ea7c7e88ec03ce7484d89fe244390e628bc04b824e78dc62f0d12df46f100fcd70a1cc2783360150eaee4b9b6928700cb776e5b84abc69565c04e97800c615c84e640fb7b971cdd88ca6478f8d07a28058dd50ab7879c3340ad84d7c6e9fb779710a060cc6d26cbdb0ab7e7f8b70ffd77e025470569f0be3580991c83d6db4b78c2f7e75713c73c8683feebeded81088e8706b23c64747f20084e726f0de41906254a0f0983430a990861e8ddd9fd1d832b872aebac5573358cc3c0659257bfcf54763ec1c5ecff3b3fbd1d4c';

$url = getrealurl($url);
echo 'enenba真实的url为:'.$url;


?>

看到百度再怎么301跳转我都可以找得到。

 

end

从nutch索引里面,读取文章内容

nutch作为一个完整的搜索引擎,是广大搜索爱好者学习的一个好项目。然而,因为nutch自己封装了一套严谨的IO操作类,要查看原始网页的内容,也不容易。在毕业设计的过程中,经过一般的摸索,可以由索引得到每个网页的原始内容。因此,后继的文本分类的研究也得以展开。代码如下:

import org.apache.lucene.search.IndexSearcher;
import java.io.*;
import org.apache.lucene.document.Document;
import org.apache.nutch.searcher.FetchedSegments;
import org.apache.nutch.fs.LocalFileSystem;
import java.util.ArrayList;
import java.util.Enumeration;
import org.apache.lucene.document.Field;
import org.apache.nutch.searcher.HitDetails;
public class ExtractText {
 public ExtractText() {
 }
 public static void main(String[] args) throws IOException {

   String path = args[0];//nutch crawl完的主目录 如crawl-20060622203455
   File nutchFileRoot = new File(path);
   File index = new File(nutchFileRoot,”index”);
   File segmentsDir = new  File(nutchFileRoot,”segments”);
   File outPut = new File(nutchFileRoot,”plaitext”);//存放内容的目录
   if(!outPut.isDirectory()){
     outPut.mkdir();
   }

   FetchedSegments segments = new FetchedSegments(new LocalFileSystem(), segmentsDir.toString());

   try {
     IndexSearcher searcher = new IndexSearcher(index.getAbsolutePath());
     
     for(int i = 0;i<searcher.maxDoc();i++){
       Document doc = searcher.doc(i);//依次遍历索引库中的每条记录
        
        String docNo = doc.get(“docNo”);
        String seg  = doc.get(“segment”);

        ArrayList fields = new ArrayList();
        ArrayList values = new ArrayList();

        Enumeration e = doc.fields();
        while (e.hasMoreElements()) {
          Field field = (Field)e.nextElement();
          fields.add(field.name());
          values.add(field.stringValue());
        }
       HitDetails detail = new HitDetails((String[])fields.toArray(new String[fields.size()]),
                              (String[])values.toArray(new String[values.size()]));
       
       String aa = segments.getParseText(detail).toString();//得到内容
       
       File temp =  new File(outPut,seg+”_”+docNo);//输出文件的名字,可以随便起,保证不重复就可以
       DataOutputStream outs = new DataOutputStream(new FileOutputStream(temp));
       outs.write(aa.getBytes());
       outs.close();

     }
   } catch (IOException ex) {
     ex.printStackTrace();
   }

 }
}

转自:http://hi.baidu.com/sunky/blog/item/40702ff5c42a9b25bd310949.html

Nutch中使用自定义中文分词器

原文:http://xtfncel.iteye.com/blog/756763

Nutch中使用自定义中文分词器

Nutch对中文查询时默认采用的分词器为NutchAnalyzer,对中文默认采用单字切分.这种效果不是很理想,我们可以自定义切词器,以实现对中文支持.

通常可以采用的两种方式添加对中文的支持:

1.采用插件的方式,不修改系统代码的基础上,编写中文分词插件实现对中文分词的支持。

2.直接修改nutch的系统代码,对默认的分词器代码进行修改使其使用自定义中文分词程序.

继续阅读

Nutch中文分词总结

1 中文分词介绍

中文分词是在做检索类系统时需要重点考虑的一个因素。Nutch的本土化过程也需要更改对中文分词的支持。目前,Nutch中文分词方式大致有两种方式:

一是修改源代码。这种方式是直接对Nutch分词处理类进行修改,调用已写好的一些分词组件进行分词。

二是编写分词插件。这种方式是按照Nutch定义的插件编写规则重新编写或者添加中文分词插件。

以上两种方式都是可取的。目前,由于开源社区的活跃,已经有很多种分词组件的出现,无论是修改源代码的方式还是编写分词插件的方式,都是依赖于这些分词组件的。下面列出了主要的一些分词组件:

继续阅读