GVKun编程网logo

CrawlerProcess与CrawlerRunner

7

在本文中,我们将带你了解CrawlerProcess与CrawlerRunner在这篇文章中,同时我们还将给您一些技巧,以帮助您实现更有效的awesome-crawler、AWSGlueCrawler

在本文中,我们将带你了解CrawlerProcess与CrawlerRunner在这篇文章中,同时我们还将给您一些技巧,以帮助您实现更有效的awesome-crawler、AWS Glue Crawler 和大小写混合的 JSON 数据、AWS Glue Crawler将json文件分类为UNKNOWN、crawler

本文目录一览:

CrawlerProcess与CrawlerRunner

CrawlerProcess与CrawlerRunner

Scrapy
1.x文档
说明,有两种方法可以 通过脚本运行Scrapy Spider

  • 使用 CrawlerProcess
  • 使用 CrawlerRunner

两者有什么区别?我什么时候应该使用“进程”,什么时候应该使用“运行器”?

awesome-crawler

awesome-crawler

awesome-crawler 介绍

互联网爬虫,蜘蛛,数据采集器,网页解析器的汇总,因新技术不断发展,新框架层出不穷 

Python

Scrapy - 一种高效的屏幕,网页数据采集框架。

django-dynamic-scraper - 基于Scrapy内核由django Web框架开发的爬虫。

Scrapy-Redis - 基于Scrapy内核采用Redis组件的爬虫。

scrapy-cluster - 基于Scrapy内核采用Redis 和 Kafka 开发的分布式爬虫框架。

distribute_crawler - 基于Scrapy内核采用redis,mongodb开发的分布式爬虫框架。

pyspider - 一个强大纯python的数据采集系统.

cola - 一个分布式的爬虫框架.

Demiurge - 基于PyQuery的微型爬虫框架.

Scrapely - 一个纯python的html页面捕捉库.

Feedparser - 一个通用的Feed解析器.

you-get - 静默网站爬去下载器.

Grab - 网站采集框架.

MechanicalSoup - 一个自动化的互动网站Python库.

portia - 基于Scrapy的可视化数据采集框架.

crawley - 基于非阻塞通信(NIO)的Python爬虫框架.

Robobrowser - 一个简单的,不基于Web浏览器的基于Python的Web 浏览器.

MSpider - 一个基于gevent(协程网络库)的Python爬虫.

brownant - 一个轻量级的网络数据抽取框架.

Java

Apache Nutch - 用于生产环境的高度可扩展的高度可扩展的网络爬虫.

anthelion - 一个基于Apache Nutch抓取语义注释在html页面插件.

Crawler4j - 简单和轻量级的网络爬虫.

JSoup - 采集,分析,处理和清洗html页面.

websphinx - html网站特定的处理、信息提取.

Open Search Server - 全套搜索功能,建立你自己的索引策略。分析、提取全文数据,这个框架可以索引的一切.

Gecco - 一个易于使用的轻量级网络爬虫.

WebCollector -简单的抓取网页的界面,可以在不到5分钟内部署一个多线程的网络爬虫.

Webmagic -一个可扩展的爬虫框架.

Spiderman -一个可扩展的,多线程的网络爬虫.

Spiderman2 - 分布式网络爬虫框架,支持JavaScript渲染.

Heritrix3 - 可扩展,大规模的网络爬虫项目.

SeimiCrawler - 一个敏捷的分布式爬虫框架.

StormCrawler - 基于开放源代码、构建低延迟的网络资源采集框架,基于Apache Storm.

Spark-Crawler - 基于Apache Nutch 的网络爬虫,可以运行于Spark.

C#

ccrawler - 一个简单的Web内容分类方案,它可以根据其内容分开网页,基于C#3.5.

SimpleCrawler - 简单的多线程网络爬虫,基于REG表达式.

DotnetSpider - 基于C#开发的一个轻量级,交叉平台的网络爬虫.

Abot - 具有很好效率和可扩展性的C#网络爬虫.

Hawk -  用 C#/WPF开发的网络爬虫,具有简单的ETL功能.

SkyScraper - 一个支持异步网络和有很好扩展性的网络爬虫.

JavaScript

scraperjs - 基于js的一个功能齐全的网络爬虫.

scrape-it - 基于Node.js的网络爬虫.

simplecrawler - 基于事件驱动开发的网络爬虫.

node-crawler - 提供简单API,适于二次开发的网络爬虫.

js-crawler - 基于Node.js,支持HTTP(S)的网络爬虫.

x-ray - 支持分页的网络爬虫.

node-osmosis - 基于Node.js适于解析html结构的网络爬虫.

PHP

Goutte - 基于PHP的网页截屏和爬取程序.

laravel-goutte - 基于Laravel 5 的网络爬虫.

dom-crawler - 易于抽取DOM文件的网络爬虫.

pspider - 基于PHP的并发网络爬虫.

PHP-spider - 一个基于PHP的高可扩展的网络爬虫.

C++

open-source-search-engine - 基于C/C++开发的网络爬虫和搜索引擎.

C

httrack - 全部网站整体复制工具。 ## Ruby

upton - 一个易于上手的爬虫框架集合,支持css选择器.

wombat - 基于Ruby天然的支持DSL的网络爬虫,易于提取网页正文数据.

RubyRetriever - 基于Ruby的网站数据采集和全网数据收割机.

Spidr - 全站数据采集,支持无限的网站链接地址采集.

Cobweb - 非常灵活,易于扩展的网络爬虫,可以单点部署使用.

mechanize - 自动采集网站数据的框架.

R

rvest - 基于R开发的简单网络爬虫.

Erlang

ebot - 一个分布式,高可扩展的网络爬虫.

Perl

web-scraper - 方便使用html、css、XPath选择器的网络爬虫。

Go

pholcus - 一个分布式,支持高并发的网络爬虫.

gocrawl - 一个高并发的,轻量级,遵守道德的网络爬虫.

fetchbot -一个遵守robots.txt规则和延迟规则的轻量级网络爬虫.

go_spider - 一个非常好的高并发网络爬虫.

dht -支持DHT协议的网络爬虫.

ants-go - 基于Golang的高并行网络爬虫.

scrape - 一个简单的提供很好开发接口的网络爬虫.

Scala

crawler - 基于Scala DSL的网络爬虫.

scrala - 由Scala开发基于scrapy内核的网络爬虫.

ferrit - 基于Scala开发使用了Akka,Spray,Cassandra的网络爬虫.

GitHub:https://github.com/BruceDone/awesome-crawler

网站描述:爬虫技术资源汇总

awesome-crawler官方网站

官方网站:

如果觉得小编网站内容还不错,欢迎将小编网站 推荐给程序员好友。

AWS Glue Crawler 和大小写混合的 JSON 数据

AWS Glue Crawler 和大小写混合的 JSON 数据

如何解决AWS Glue Crawler 和大小写混合的 JSON 数据?

我们正在将 JSON 文件发送到 S3,稍后由 glue Crawler 解析,然后在 Athena 中使用。

问题是某些文件带有小写的属性名称,而其他文件带有 CamelCase 属性名称。

Crawler 基本上将两个模式作为单独的模式添加,所以最后我在同一个表中有这样的内容:

structobject: struct
StructObject: struct

后来 Athena 拒绝查询抛出 GENERIC_INTERNAL_ERROR: Ambiguous field 错误。

有没有办法告诉 Crawler 在涉及架构时使用不区分大小写的比较?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

AWS Glue Crawler将json文件分类为UNKNOWN

AWS Glue Crawler将json文件分类为UNKNOWN

我正在进行ETL作业,该作业将JSON文件提取到RDS登台表中。我配置的搜寻器对JSON文件进行分类,只要它们的大小小于1MB。如果我缩小文件(而不是漂亮的打印件),并且结果小于1MB,它将对文件进行分类而不会出现问题。

我在想办法时遇到了麻烦。我尝试将JSON转换为BSON或GZIPing JSON文件,但仍被归类为UNKNOWN。

还有其他人遇到这个问题吗?有一个更好的方法吗?

crawler

crawler

#!/usr/bin/perl
use strict;
use warnings;
 
use threads;
use threads::shared;
use Thread::Queue;
use Thread::Semaphore;
 
use Bloom::Filter;
use URI;
use URI::URL;
use Web::Scraper;
use LWP::Simple;
 
use LWP::UserAgent;
use HTTP::Cookies;
 
#use HTTP::Cookies::Guess;
 
use String::Diff;
use String::Diff qw(diff_fully diff diff_merge diff_regexp) ;
use URI::Split qw(uri_split uri_join) ;
 
my $fid : shared; #下载的页面以递增的数字命名
share( $fid );    #多线程共享该变量
$fid =0;
 
#crawling with signed cookie
my $cookie_jar = '.mozilla/firefox/bg146ia6.default/cookies.sqlite' ;
 
my $tmp_ua = LWP::UserAgent->new;    #UserAgent用来发送网页访问请求
$tmp_ua ->timeout(15);                ##连接超时时间设为15秒
$tmp_ua ->protocols_allowed( [ 'http' , 'https' ] ); ##只允许http和https协议
$tmp_ua ->agent(
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727;.NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
   )
   ; ##用来在header中告诉服务器你用的是什么"浏览器",设置文件头的User-Agent
 
$tmp_ua ->cookie_jar(HTTP::Cookies->new( 'file' => "$ENV{'HOME'}/$cookie_jar" , 'autosave' =>1));
# 设置cookie,在运行过程中必须执行两个方法,extract_cookies($request) 和 add_cookie_header($response)。在运行的过程中实际用到了HTTP::Cookies模块。如:
# $ua->cookie_jar({ file => "$ENV{HOME}/.cookies.txt" });
# 等价于
# require HTTP::Cookies;
# $ua->cookie_jar(HTTP::Cookies->new(file => "$ENV{HOME}/.cookies.txt"));
 
push @{ $tmp_ua ->requests_redirectable}, 'POST' ; #告诉LWP在POST请求发送后如果发生重新定向就自动跟随
 
my $max_threads = 5;
 
my $base_url = $ARGV [0] || 'http://www.cnblogs.com/zhangchaoyang/' ;
my $host = URI::URL->new( $base_url )->host;
print "Host Name: $host.\n" ;
 
my $queue = Thread::Queue->new( );       #线程队列,每个线程负责去处理一个url
 
my $semaphore = Thread::Semaphore->new( $max_threads );
my $mutex = Thread::Semaphore->new( 1 );
 
 
#my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
#my $logfile = "crawler".($year+1900).($mon+1).$mday.$hour.$min.$sec.".log";
#open(BANLOG,">>$logfile") or die("can't open logfile:$!\n");
 
# Bloom::Filter使用更少的内存采用一种基于概率的算法来进行存在性测试。
my $filter = shared_clone( Bloom::Filter->new( capacity => 1000000, error_rate => 0.001) );
 
$queue ->enqueue( $base_url );        #放入线程队列的URL就要被线程所处理
$filter ->add( $base_url );           #放入filter中好判断该URL是否已经存在
 
my @tmp_url = ();                   #@tmp_url存在处理过的url
push ( @tmp_url , $base_url );
 
while ( 1 )
{
     # join所有可以被join的线程
     #my $joined = 0;
     foreach ( threads->list(threads::joinable) )
     {
         #$joined ++;
         $_ -> join ( );
     }
     #print $joined," joinedn";
 
     # if there are no url need process.
     my $item = $queue ->pending(); #返回队列中url的个数
     # 线程队列为空
     if ( $item == 0 )
     {
         my $active = threads->list(threads::running);
         # 已经没有active线程了,结束所有的工作
         if ( $active == 0 )
         {
             print "All done!\n" ;
             last ;
         }
         # 如果还有活动线程,那么主线程sleep,等待处理URL的子线程结束
         else
         {
             #print "[MAIN] 0 URL,but $active active threadn";
             sleep 1;
             next ;
         }
     }
 
     # 线程队列不为空,信号量减1,占用一个线程来处理url
     #print "[MAIN] $item URLn";
     $semaphore ->down;
     #print "[MAIN]Create thread.n";
     threads->create( \ &ProcessUrl );
}
 
# join all threads which can be joined
foreach ( threads->list() )
{
     $_ -> join ( );
}
 
sub ProcessUrl
{
     my $scraper = scraper
     {
             process '//a' , 'links[]' => '@href' ; #根据XPath表达式寻找所有的标签a,把href属性存到散列的value中
     };
 
     my $res ;
     my $link ;
 
     while ( my $url = $queue ->dequeue_nb() )
     {
         eval #eval BLOCK,BLOCK只会被解析一次,并且在编译时进行代码语法检查。
        {
             print "开始下载" ,URI->new( $url )->as_string, "\t\$fid=$fid\n" ;
             LWP::Simple::getstore(URI->new( $url )->as_string, "$ENV{'HOME'}/master/cnblog/cn$fid" ) or print "Can't download the web page." ;
             $fid +=1;
             $scraper ->user_agent( $tmp_ua ); #设置$scraper的user_agent
             $res = $scraper ->scrape( URI->new( $url ) )->{ 'links' }; #把URI传给scrape函数。scrape函数返回一个数组引用,因为links是数组
         };
         if ( $@ ) # 当BLOCK中有语法错误、运行时错误遇到 die 语句, eval 将返回 undef 。错误码被保存在 $@ 中。
         {
             warn "$@\n" ;
             next ;
         }
         next if (! defined $res ); #如果HTML文档中没有发现a标签
 
         #print "there are ".scalar(threads->list(threads::running))." threads,",$queue->pending()," urls need process.n";
 
         foreach ( @{ $res } )
         {
             # $_ => URI->new("http://example.com/")     所以要调用sa_string来获取"http://example.com/"
             $link = $_ ->as_string;
             $link = URI::URL->new( $link , $url );
             #$u1 = URI::URL->new($str,$base);
             #$u2 = $u1->abs;
 
             # not http and not https?
             next if ( $link ->scheme ne 'http' && $link ->scheme ne 'https' );
             #The three forms of URI reference Syntax are summarized as follows:
             #<scheme>:<scheme-specific-part>#<fragment>
             #<scheme>://<authority><path>?<query>#<fragment>
             #<path>?<query>#<fragment>
             #可以通过URL::Split把名个部分分离出来
             # another domain?
             # next if( $link->host ne $host );
 
             #search for the sub domain
             next if (!( $link ->host =~ / $host /));
 
             $link = $link -> abs ->as_string; #获得绝对路径
 
             if ( $link =~ /(.*?) #(.*)/ )#去除书签锚点,即#以后的内容
             {
                 $link = $1;
             }
 
             next if ( $link =~ /RSS|.(jpg|png|bmp|mp3|wma|wmv|gz|zip|rar|iso|pdf)$/i ); #这些文件格式我们不抓取
 
 
             #print "test:$link\n";
 
             #EscapeUrl,skip query form values
             my $tmp_link = &EscapeUrl ( $link ); #$tmp_link中已经把查询参数的值去掉了
             #print "Escape:".$tmp_link."\n";
 
             $mutex ->down(); #互质体减1,进入线程临界资源区
             my $tmp_mark = 0;
 
             #print "test start:$link\n";
             if ( ! $filter ->check( $tmp_link ) )    #如果$tmp_link不在$filter中
             {
                 #print "Test filter ok:$tmp_link\n";
 
                 #DiffUrl,diff $link from queue with number
 
                 foreach ( @tmp_url )
                 {
                     #print "Test Queue:".$tmpurl."\n";
                     #print "test-1:$_\ntest-2:$tmp_link\n";
                     if ( &DiffUrl ( $_ , $link )) #如果发现@tmp_url中的url和当前页面中的一个链接url仅是在某些数字上不同(很可能是查询参数值不同),则跳过该链接,即跳到else里面去。
                     {
                         $tmp_mark = 2;
                         last ;
                     }
                 }
 
                 if ( $tmp_mark != 2 )
                 {
                     $queue ->enqueue( $link );      #把页面上的链接$link交给线程进行处理
                     #print "add queue:$link\n";
                     $filter ->add( $tmp_link ); #$tmp_link放入$filter
                     #print "add filter:$tmp_link\n";
                     #print BANLOG $filter->key_count()," ",$link,"\n";
                     #print $filter->key_count(),"\n";
 
                     push ( @tmp_url , $link ); #把$link放入已处理的url数组@tmp_url
                 }
                 else
                 {
                     #print "pass:$link\n";#$link被忽略
                 }
             }
             #print "pass:$link\n";
 
             $mutex ->up(); #互斥信号量加1
             undef $link ;
         }
         undef $res ; #清除创建的一些object,否则在while循环中这些object越积越多
     }
     undef $scraper ;
     $semaphore ->up( ); ##普通信号量加1
}
 
#close(BANLOG);
print "ALL DONE.\n" ;
 
#把URL尾部的request参数置为空
#比如http://category.dangdang.com/?ref=www-0-C&name=orisun-zhang#ref=www-0-C被处理为http://category.dangdang.com/?ref=&name=
sub EscapeUrl
{
     my $urlold = shift ;
     my ( $scheme , $auth , $path , $query , $frag ) = uri_split( $urlold ); #把一个url的各部分分离出来
     my $urlnew = uri_join( $scheme , $path );
 
     my $u = URI->new( $urlold );
     my @tmp_array = $u ->query_form();
     my $tmp = '' ;
     my $i = 0;
     for ( $i =0; $i < @tmp_array ; $i +=2) #把request参数的值去掉
     {
         $tmp .= $tmp_array [ $i ]. "=&" ;
     }
     if ( @tmp_array != 0)
     {
         $tmp =~ s/&$//;
         $urlnew .= "?" . $tmp ;
     }
     undef $u ; #清除子例程中创建的object
     #print $urlnew."\n";
     return $urlnew ;
}
 
sub DiffUrl
{
     my $urlold = shift ;
     my $urlnew = shift ;
     my $urloldx = &EscapeUrl ( $urlold );
     my $urlnewx = &EscapeUrl ( $urlnew );
 
     my ( $old , $new ) = String::Diff::diff( $urloldx , $urlnewx );
     #my($old,$new) = String::Diff::diff($urlold,$urlnew);
     if (( $old =~ m/(\[\d+\])/i) && ( $new =~ m/{\d+}/i))         #如果两个url仅是在某些数字上不同
     #if ($new =~ m/{\d+}/i)
     {
         #print "test num success.\n";
         return 1;
     }
     else
     {
         #print "test num Failed.\n";
         return 0;
     }
}

关于CrawlerProcess与CrawlerRunner的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于awesome-crawler、AWS Glue Crawler 和大小写混合的 JSON 数据、AWS Glue Crawler将json文件分类为UNKNOWN、crawler的相关知识,请在本站寻找。

本文标签: