Hadoop中的Java代码

Hadoop中的Java代码,java,hadoop,jsoup,Java,Hadoop,Jsoup,我正在Hadoop中运行一个仅映射的作业。数据集是单个文件中的一组html页面(由爬虫程序返回) 映射程序代码是用Java编写的。我正在使用JSoup进行解析。我想要的输出是一个既有title标签内容又有meta标签内容的键。理想情况下,我应该为我的地图输出记录获得1592条记录。我得到3184 我试图用这行代码进行的连接没有发生 String MN_Job = (jobT + "\t" + jobsDetail); 相反,我得到的是每一个单独的输出,因此输出的数量增加了一倍。我

我正在Hadoop中运行一个仅映射的作业。数据集是单个文件中的一组html页面(由爬虫程序返回)

映射程序代码是用Java编写的。我正在使用JSoup进行解析。我想要的输出是一个既有title标签内容又有meta标签内容的键。理想情况下,我应该为我的地图输出记录获得1592条记录。我得到3184

我试图用这行代码进行的连接没有发生

       String MN_Job = (jobT + "\t" + jobsDetail);
相反,我得到的是每一个单独的输出,因此输出的数量增加了一倍。我做错了什么

public class JobsDataMapper extends Mapper<LongWritable, Text, Text, Text> {

    private Text keytext = new Text();
    private Text valuetext = new Text();

    @Override
    public void map(LongWritable key, Text value, Context context)
    throws IOException, InterruptedException {

        String line = value.toString();

        Document doc = Jsoup.parse(line);
        Elements desc = doc.select("head title, meta[name=twitter:description]");

        for (Element jobhtml : desc) {
            Elements title = jobhtml.select("title");
            String jobT = "";
            for (Element titlehtml : title) {
                jobT = titlehtml.text();
            }

            Elements meta  = jobhtml.select("meta[name=twitter:description]"); 
            String jobsDetail ="";

            for (Element metahtml : meta) {
                String content = metahtml.attr("content");
                String content1 = content.replaceAll("\\p{Punct}+", " ");
                jobsDetail = content1.replaceAll(" (?i)a | (?i)able | (?i)about | (?i)across | (?i)after | (?i)all | (?i)almost | (?i)also | (?i)am | (?i)among | (?i)an | (?i)and | (?i)any | (?i)are | (?i)as | (?i)at | (?i)be | (?i)because | (?i)been | (?i)but | (?i)by | (?i)can | (?i)cannot | (?i)could | (?i)dear | (?i)did | (?i)do | (?i)does | (?i)either | (?i)else | (?i)ever | (?i)every | (?i)for | (?i)from | (?i)get | (?i)got | (?i)had | (?i)has | (?i)have | (?i)he | (?i)her | (?i)hers | (?i)him | (?i)his | (?i)how | (?i)however | (?i)i | (?i)if | (?i)in | (?i)into | (?i)is | (?i)it | (?i)its | (?i)just | (?i)least | (?i)let | (?i)like | (?i)likely | (?i)may | (?i)me | (?i)might | (?i)most | (?i)must | (?i)my | (?i)neither | (?i)no | (?i)nor | (?i)not | (?i)nbsp | (?i)of | (?i)off | (?i)often | (?i)on | (?i)only | (?i)or | (?i)other | (?i)our | (?i)own | (?i)rather | (?i)said | (?i)say | (?i)says | (?i)she | (?i)should | (?i)since | (?i)so | (?i)some | (?i)than | (?i)that | (?i)the | (?i)their | (?i)them | (?i)then | (?i)there | (?i)these | (?i)they | (?i)this | (?i)tis | (?i)to | (?i)too | (?i)twas | (?i)us | (?i)wants | (?i)was | (?i)we | (?i)were | (?i)what | (?i)when | (?i)where | (?i)which | (?i)while | (?i)who | (?i)whom | (?i)why | (?i)will | (?i)with | (?i)would | (?i)yet | (?i)you | (?i)your "," ");
            }

            String IT_Job = (jobT + "\t" + jobsDetail);

            keytext.set(IT_Job) ;
            valuetext.set("JobDetail");
            context.write( keytext, valuetext );        
        }
    }
}
public类作业datamapper扩展映射器{
私有文本keytext=新文本();
私有文本值Text=新文本();
@凌驾
公共void映射(可长写键、文本值、上下文)
抛出IOException、InterruptedException{
字符串行=value.toString();
文档doc=Jsoup.parse(行);
Elements desc=doc.select(“head title,meta[name=twitter:description]”;
for(元素jobhtml:desc){
Elements title=jobhtml.select(“title”);
字符串jobT=“”;
for(元素标题html:title){
jobT=titlehtml.text();
}
Elements meta=jobhtml.select(“meta[name=twitter:description]”;
字符串jobsDetail=“”;
for(元素metahtml:meta){
String content=metahtml.attr(“content”);
字符串content1=content.replaceAll(“\\p{Punct}+”,”);
(2)关于(我)关于(我)关于(我)关于(我)关于(我)关于(我)关于(我)关于(我)关于(我)关于(我)关于(我)横横横穿(我)跨越(我)在(我)在(我)在(我)的)关于(我)关于(我)关于(我)关于(我)的)关于(我)关于(我)横横横穿)的,我)在(我)过去)之后(我)之后(我)所有(我)所有(我)所有)所有(我)所有(我)所有(我)所有(我)几乎(我)几乎(我)几乎(我)几乎(我)几乎(我)几乎(我)(我)是)的)的)是(我)(我)的)几乎(我)是(我)(我)是)(我)(我)的)(我)(我)我)是)的)的)的)几乎(我(我)是)的)的)是(我)(我)的)的)(我)可以(我)不能(我)可以(我)亲爱的(我)做过(我)做过(我)做过(我)也做过(我)我)常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用常用| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |(我)不(我)或(我)不(我)不(我)不(我)或(我)不(我)不(我)不(我)不(我)不(我)必须(我)必须(我)我(我)的我(我)的我)的(我)的(我)的(我)的)我)的(我)的(我)的)的(我)的(我)的(我)的)的(我)的(我)的(我)的(我)的(我)的(我)的)的(我)的(我)的)的(我)的)的(我)的(我)的(我)的)的(我)的(我)的)的(我)的)的(我)的)的(我)的)的(我)的(我)的)的(我)的)的(我)的)的(我)的)的)我)的)的(我)的)的)的(我)的)的)(我)因为(我)所以(我)一些(我)比(我)那个(我)他们的(我)他们的(我)然后(我)那里这些(我)他们(我)他们(我)他们(我)他们(我)他们(我)他们(我)他们(我)他们(我)他们(我)他们(我)他们(我)他们(我)他们(我)他们(我)他们(我)他们(我)他们(我)这些(我)这个(我)这个(我)这个(我)我)这个(我)本(我)我)我(我)我)是(我)我)本(我)我)我(我)是(我)我)我)我(我)这个(我)我)我(我)我)我(我)我)我)我(我)我(我)我(我)我)我)我(我(我)我(我)我)我(我)我(我)我)我)我(我(我)我)我(我)我)我(我)我)我(我)我)我)我(我)我(我)我)我(我)我)我)我有了| | | | | | | | | | | | | | | | | | | | | | |;
}
字符串IT_Job=(jobT+“\t”+jobsDetail);
设置(IT_作业);
valuetext.set(“作业详细信息”);
context.write(键文本、值文本);
}
}
}

编辑:我知道问题出在哪里。但问题是,解决方案在MapReduce中可能并不明显。您可能需要编写自定义的
RecordReader
。让我解释一下这个问题

在代码中,您逐行阅读。然后将其应用于您阅读的行:

Elements desc = doc.select("head title, meta[name=twitter:description]");
但显然,它可能只有
标题
标记。所以你读了其中的一个并储存起来。另一个保持空白。因此,每次只有一个变量,
jobT
jobsDetail
有任何数据。因此,对于代码片段:

String IT_Job = (jobT + "\t" + jobsDetail);
一次,第一次为空,第二次,另一次为空。因此,如果您需要
n个
记录,则会得到
2n个
记录。类似地,如果您试图提取三个字段,那么应该得到
3n
记录。因此,您可以通过提取另一个字段,然后检查您是否获得了预期记录数的三倍来测试此理论


如果理论证明是正确的,您可能希望用特定的分隔符字符串分隔提取的网页。然后,您需要编写一个自定义的
RecordReader
,它将根据分隔符一次读取一个html文件,然后一次处理整个html文件。这样你就可以把
标题
标记放在一起。

只需看一下数字:
3184/2=1592

我认为您的文件只是在输入文件夹中复制了。我不能确定,因为您还没有给出如何提交作业的代码,但是您可以用一个简单的方法进行验证:

 bin/hadoop fs -ls /your/input_path 

提交时,请确保其中只有一个文件,或者只在提交逻辑中引用该文件。

我对原始代码进行了更改,删除了不必要的循环。旧代码中发生的情况是,当记录中有标题时,它是输出的,后来有内容时,它也是输出的。因此,每个HTML文件有两次写入

        public class JobsDataMapper extends Mapper<LongWritable, Text, Text, Text> {
        private Text keytext = new Text();
        private Text valuetext = new Text();
        private String jobT = new String();
        private String jobName= new String();

         @Override
        public void map(LongWritable key, Text value, Context context)
        throws IOException, InterruptedException {



 String line = value.toString();

 Document doc = Jsoup.parse(line);
 Elements desc = doc.select("head title, meta[name=twitter:description]");

 for (Element jobhtml : desc){
 Elements title = jobhtml.select("title");


 String jobTT = title.text();
 jobT =jobTT ;

 if (jobT.length()> 0){

 jobName=jobTT;
 }

 Elements meta = jobhtml.select("meta[name=twitter:description]");
 String jobsDetail ="";

 String content = meta.attr("content");

 String content1 = content.replaceAll("\\p{Punct}+", " ");
 jobsDetail = content1.toLowerCase();
 jobsDetail = content1.replaceAll(" a| able | about | across | after | all | almost | also | am | among | an | and | any | are | as | at | be| because | been | but | by | can | cannot | could | dear | did | do | does | either | else | ever | every | for | from | get | got | had | has | have | he | her | hers | him | his | how | however | i | if | in | into | is | it | its | just | least | let | like | likely | may | me | might | most | must | my | neither | no | nor | not | nbsp | of | off | often | on | only | or | other | our | own | rather | said | say | says | she | should | since | so | some | than | that | the | their | them | then | there | these | they | this | tis | to | too | twas | us | wants | was | we | were | what | when | where | which | while | who | whom | why | will | with | would | yet | you | your "," ");




     if (jobsDetail.length()>0) {

String MN_Job = (jobName+ "\t" + jobsDetail);

keytext.set(MN_Job) ;
valuetext.set("JobInIT");
context.write( keytext, valuetext );

 }

 }

 }

 }
public类作业datamapper扩展映射器{
私有文本keytext=新文本();
私有文本值Text=新文本();
私有字符串jobT=新字符串();
私有字符串jobName=新字符串();
@凌驾
公共void映射(可长写键、文本值、上下文)
抛出IOException、InterruptedException{
字符串行=value.toString();
文档doc=Jsoup.parse(行);
Elements desc=doc.select(“head title,meta[name=twitter:description]”;
for(元素jobhtml:desc){
Elements title=jobhtml.select(“title”);
字符串jobTT=title.text();
jobT=jobTT;
如果(作业长度()>0){
jobName=jobTT;
}
Elements meta=jobhtml.select(“meta[name=twitter:description]”;
字符串jobsDetail=“”;
字符串内容=meta.attr(“内容”);
字符串content1=content.replaceAll(“\\p