设为首页 加入收藏

TOP

通过亚马逊电影评论的数据包抓取电影名称---Perl多线程同步及DBI编程(一)
2015-11-21 01:40:21 来源: 作者: 【 】 浏览:2
Tags:通过 亚马逊 电影 评论 数据 包抓取 名称 ---Perl 线程 同步 DBI 编程
读这篇文章你可以了解:
?
1.Perl多线程同步并行的几种方法及实现
?
2.Perl与mysql/mariadb的通信
?
3.如何利用Perl处理串的优势,直接快速锁定HTML文档中的目标,避免庞杂的HTML树结构搭建过程
?
你也会同时了解到以下的Perl编程技巧:
?
(1)利用perl的内置哈希结构迅速实现“去重”
?
(2)滑窗法/栈法实现线程并行
?
(3)分段法实现线程并行
?
(4)如何解决can't locate object method '_uric_escape'..报错
?
(5)如何利用HTML::TreeBuilder创建一个完整描述一份HTML文档的数据结构
?
任务目标:
?
这其实是斯坦福大学计算机专业的一次课程作业:http://snap.stanford.edu/data/web-Movies.html
?
在以上的链接中的 movies.txt.gz 文件大小为3G左右,解压后的电影评论有9G左右,我们需要做的事情就是围绕这个解压后的movies.txt文件中的内容而展开的!
?
先大概介绍下具体要做的是什么事情:
?
1. 首先需要从movies.txt文件中扫描出来所有的叫做productId的字符串,这里有一个去重的过程,再导入数据库,文件中的格式大致是这个样子的。
?
product/productId: B00006HAXW
review/userId: A1RSDE90N6RSZF
review/profileName: Joseph M. Kotow
review/helpfulness: 9/9
review/score: 5.0
review/time: 1042502400
review/summary: Pittsburgh - Home of the OLDIES
review/text: I have all of the doo wop DVD's and this one is as good or better than the 1st ones. Remember once these performers are gone, we'll never get to see them again.Rhino did an excellent job and if you like or love doowop and Rock n Roll you'll LOVE this DVD !!

?

2. 扫描得到的productId(如上例中的 B00006HAXW)和一个(http://amazon.com/dp/)前缀组合起来会成为一个指向一份亚马逊电影商品的HTML资源的URL(http://amazon.com/dp/B00006HAXW),我们需要在这份HTML文档中抓到电影的名字,不同的productId还有可能指向名字相同的电影名,有的相同的电影也有可能在网页上的名字不同(例如:Film 和 Film:director..actor..[VHS]),最后统计并且得到所有电影的名字。
?
技术铺垫:
?
(1)Perl-DBI-mysql简单搭建 #Perl-DBI其实真正实践并没有使用,不想看的朋友可以直接忽略
?
使用Perl-DBI的原因是为了处理更大规模的数据,甚至达到硬盘规模的数据。这里只是一个数据存放位置的区别,由于本次需要处理的数据最大初始规模就是9G+,所以可以交付给文件系统处理,甚至可以直接放入内存之中(虚拟内存),事实上在后面统计效率的时候就是直接在内存之中进行处理的,好我们先假设数据规模大到文件系统无法处理,开始使用DBI进行数据处理,我们的表的格式很简单:
?
drop table TestTable;

create table TestTable(
id int primary key auto_increment,
name varchar(200) not null
);

?

其实表的结构中,可以直接用name用来做为主键,这样的话就间接完成了一个去重的过程(数据库主键不能重复)。在Perl-DBI中我们需要使用到两个模块,如果没有安装,windows下请使用ppm安装,linux下直接使用cpan客户端进行安装。
?
use DBI;
use DBD::mysql;
?
创建和mysql数据的互联,只需要如下一句perl脚本:
?
1 my $ddesc="DBI:mysql:test:127.0.0.1:3306";
2 my $usr="root";
3 my $passwd="jinmin";
4?
5 my $dbh=DBI->connect($ddesc,$usr,$passwd,{RaiseError=>0,PrintError=>1}) or die "Cannot Open Database!";
?所有的sql数据操作语句包括“增删改查”,下例不妨就使 my $sql="select * from testtable where testtable.id=?";
?
1 my $stmt=$dbh->prepare($sql);
2?
3 $stmt->execute(1) or die "Cannot Prepare SQL Statement!";
?
执行完之后,调用$stmt对象的fetchrow_array方法会返回一个引用数组包含所有的查询结果!在执行完所有的数据操作之后就可以断开连接,用以下代码做收尾工作:
?
1 $dbh->disconnect();
?
(2)Perl-多线程编程及并行处理
?
说到Perl多线程就不得不说到线程间互斥并行,而Perl对多线程的支持确实不够强大,而且中文文档也非常少,所以以下介绍几种比较常见的实现perl线程互斥实现多线程并行的策略。
?
0. perl内置的多线程支持
?
Perl内置关键字async来实现多线程互斥,但是这里的多线程更多的指的是外部解释命令行的fork或者c程序中的fork函数,这样在脚本顺序执行的时候到达用async包裹的程序块就可以使其互斥地进入从而避免一些错误,这有点类似于java中的synchronized关键字,顺便带上一个我写的一个简单多线程并行的实现样例脚本:http://files.cnblogs.com/files/guguli/multi_thread_concurrency.rar
?
(这一段是个人的经验没有深入考究,没有兴趣请忽略)Perl另外一个关键字的组合也可以用来就是state和shared关键字,使用之前需要如下的声明:
?
1 use feature qw/state/;
2 use threads::shared;
具体的使用在上一个链接的压缩文件中的脚本中有体现!
?
1. 滑窗法/栈法实现多线程并行
?
栈法的实现非常简单,实质就是维持一个全局的栈,由于perl中内置支持的数组,又由于shift/unshift和push/pop,使得间接内置支持了队列和栈结
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Base: 一种 Acid 的替代方案 下一篇索引修改内幕

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: