Board logo

标题: [其他] [已解决]如何提取海词在线词典中的“海词释义常用度分布图” [打印本页]

作者: qixiaobin0715    时间: 2019-8-21 09:54     标题: [已解决]如何提取海词在线词典中的“海词释义常用度分布图”

本帖最后由 qixiaobin0715 于 2019-8-28 14:07 编辑

给出一个单词列表文本文件,如何提取对应的海词释义常用度分布图。
http://dict.cn/
作者: 523066680    时间: 2019-8-21 11:12

图是HTML+JS的

数据可以很直接的抓出来
  1. use utf8;
  2. use Encode;
  3. use File::Slurp;
  4. use Mojo::UserAgent;
  5. use URI::Escape;
  6. use JSON qw/from_json to_json/;
  7. STDOUT->autoflush(1);
  8. my $word = "command";
  9. my $url = "http://dict.cn/${word}";
  10. my $ua = Mojo::UserAgent->new();
  11. my $res = $ua->get($url)->result;
  12. my $json = $res->dom->at(".dict-chart")->attr("data");
  13. my $data = from_json(uri_unescape($json));
  14. if ( scalar keys %$data == 1 )
  15. {
  16.     printf "%2s%% %s\n", $data->{1}{percent}, gbk($data->{1}{pos});
  17. }
  18. else
  19. {
  20.     for my $k ( sort keys %$data )
  21.     {
  22.         printf "%2s%% %s\n", $data->{$k}{percent}, gbk($data->{$k}{sense});
  23.     }
  24. }
  25. sub gbk { encode('gbk', $_[0]) }
复制代码
  1. 74% 命令
  2. 21% 指挥
  3. 4% 掌握
  4. 1% 博得
复制代码

作者: qixiaobin0715    时间: 2019-8-21 13:18

谢谢版主!我对批处理还不是太熟悉,上面脚本文件是否还需要安装第三方工具包?并且我的意思是按照单词列表文本文件同时提取若干个单词信息。希望再做指点。
作者: 523066680    时间: 2019-8-21 16:15

Strawberry Perl
http://strawberryperl.com/releases.html
需要门槛,不推荐使用。纯粹路过……
作者: qixiaobin0715    时间: 2019-8-21 17:34

回复 4# 523066680
还是要谢谢!
作者: zaqmlp    时间: 2019-8-21 23:22

本帖最后由 zaqmlp 于 2019-8-22 14:15 编辑
  1. <# :
  2. cls
  3. @echo off
  4. mode con lines=3000
  5. cd /d "%~dp0"
  6. powershell -NoProfile -ExecutionPolicy bypass "&{[ScriptBlock]::Create([IO.File]::ReadAllText('%~f0',[Text.Encoding]::Default)).Invoke()}"
  7. pause
  8. exit
  9. #>
  10. function gethtml($w){
  11.     $html='';
  12.     $url='http://dict.cn/'+$w;
  13.     $web=New-Object System.Net.WebClient;
  14.     $web.Encoding=[System.Text.Encoding]::UTF8;
  15.     for($i=1;$i -le 4;$i++){
  16.         try{
  17.             $html=$web.DownloadString($url);
  18.             break;
  19.         }catch{write-host ('获取网页内容第'+$i.toString()+'次失败')};
  20.     };
  21.     return $html;
  22. };
  23. function gethz($s){
  24.     $str='';
  25.     $str=[regex]::replace($s,'\\u([\da-z]{4})',{param($a);[char][Convert]::ToInt32($a.groups[1].value, 16)});
  26.     return $str;
  27. };
  28. $inputfile='单词列表.txt';
  29. $outfile='结果.txt';
  30. $min=5;
  31. [void][Reflection.Assembly]::LoadWithPartialName('System.Web');
  32. [System.Collections.ArrayList]$s=@();
  33. $text=[IO.File]::ReadAllLines($inputfile,[Text.Encoding]::Default);
  34. for($i=0;$i -lt $text.count;$i++){
  35.     write-host ('------------'+$text[$i]+'------------');
  36.     $content=gethtml $text[$i];
  37.     $m=[regex]::match($content,'<div .*?id="dict-chart-basic" data="([^"]+?)"');
  38.     if($m.success){
  39.         $js=[Web.HttpUtility]::UrlDecode($m.groups[1].value);
  40.         $tmp=(gethz $js) -replace '^\{|\}$','';
  41.         $mm=[regex]::matches($tmp,'\{([^\}]+?)\}');
  42.         [System.Collections.ArrayList]$t=@();
  43.         if($mm.count -ge 1){
  44.             foreach($it in $mm){
  45.                 $arr=$it.groups[1].value.split(':,', 4);
  46.                 if((1*$arr[1]) -ge $min){[void]$t.add($arr[3].Trim('"')+':'+$arr[1])};
  47.             };
  48.         };
  49.         [void]$s.add($text[$i]+"`t"+($t -join ','));
  50.     }else{
  51.         [void]$s.add($text[$i]+"`t无");
  52.     };
  53. };
  54. [IO.File]::WriteAllLines($outfile, $s, [Text.Encoding]::Default);
复制代码

作者: qixiaobin0715    时间: 2019-8-22 09:59

回复 6# zaqmlp
效果很好,谢谢!能否再修改一下脚本,满足以下要求:
1.把提取结果写入文本文件“提取结果.txt”。
2.格式为“单词+分隔符(比如制表符)+提取结果”。
3.过滤掉percent值小于5的条目。
第3条若不易实现保留也行。
单词列表数目有否限制?
作者: zaqmlp    时间: 2019-8-22 11:22

回复 7# qixiaobin0715


    没赞助没动力
作者: qixiaobin0715    时间: 2019-8-22 12:06

回复 8# zaqmlp
尊重别人的劳动,都是在圈里混的,不会吃霸王餐的。
作者: zaqmlp    时间: 2019-8-22 13:18

回复 9# qixiaobin0715

那就扫码吧
作者: qixiaobin0715    时间: 2019-8-22 13:37

回复 10# zaqmlp

方便的话把前面的简明释义也加上吧。理解理解,现在社会的诚信有问题。已扫码。
作者: zaqmlp    时间: 2019-8-22 14:15

回复 7# qixiaobin0715


    已修改
作者: qixiaobin0715    时间: 2019-8-22 14:29

回复 12# zaqmlp

基本达到要求,我是说如果结果是这样就完美了:
  1. good adj. 好的;上等的;优秀的 ; n. 好处;善行 ;(复)goods:商品;货物. 好的:78,好处:11,优秀的:7
复制代码

作者: qixiaobin0715    时间: 2019-8-26 09:54

回复 6# zaqmlp
有空的话,还能给完善完善吗。这里先再次感谢了。
作者: flashercs    时间: 2019-8-29 12:25

本帖最后由 flashercs 于 2019-9-3 19:46 编辑
  1. <#*,:&cls
  2. @echo off
  3. pushd "%~dp0"
  4. Powershell -NoProfile -ExecutionPolicy RemoteSigned -Command ". ([ScriptBlock]::Create((Get-Content -LiteralPath \"%~0\" -ReadCount 0 | Out-String ))) "
  5. popd
  6. pause
  7. exit /b
  8. #>
  9. $VerbosePreference = "Continue"
  10. $inputFile = "单词列表.txt"
  11. $outputFile = "结果.txt"
  12. Get-Content -LiteralPath $inputFile -OutBuffer 10 | ForEach-Object -Begin {
  13.   $sw = New-Object -TypeName System.IO.StreamWriter -ArgumentList ("$pwd\$outputFile"), $false, ([System.Text.Encoding]::Default)
  14.   # webclient settings
  15.   $webclient = New-Object -TypeName System.Net.WebClient
  16.   $webclient.BaseAddress = 'http://dict.cn/'
  17.   $webclient.Encoding = [System.Text.Encoding]::UTF8
  18.   $webclient.Headers.Add("Accept", "text/html, application/xhtml+xml, application/xml; q=0.9, */*; q=0.8")
  19.   $webclient.Headers.Add("Accept-Encoding", "gzip")
  20.   $webclient.Headers.Add("Accept-Language", "en-US, en; q=0.8, zh-Hans-CN; q=0.5, zh-Hans; q=0.3")
  21.   # xml parser
  22.   $xmldoc = New-Object -TypeName System.Xml.XmlDocument
  23.   # re
  24.   $recontent = [regex]'(?si)<div\s+class="word"[^>]*>.*?(?=<div\s+class="section[^"]*"[^>]*>)'
  25.   $rejs = [regex]'(?si)<script[^>]*>.*?</script>'
  26.   # stringbuilder
  27.   $strbuilder = New-Object -TypeName System.Text.StringBuilder
  28.   Add-Type -AssemblyName Microsoft.Jscript
  29.   $vsaengine = [Microsoft.JScript.Vsa.VsaEngine]::CreateEngine()
  30.   Add-Type -AssemblyName System.Web
  31. } -Process {
  32.   Write-Verbose "Fetching $_ ..."
  33.   for ($i = 2; $i -ge 0; $i--) {
  34.     try {
  35.       $readstream = $webclient.OpenRead($_)
  36.       Write-Verbose "Fetch $_ success"
  37.       break
  38.     }
  39.     catch {
  40.       $_ | Out-String | Write-Host -ForegroundColor Red
  41.     }
  42.   }
  43.   if ($readstream) {
  44.     try {
  45.       $gzipstream = New-Object -TypeName System.IO.Compression.GZipStream -ArgumentList $readstream, ([System.IO.Compression.CompressionMode]::Decompress)
  46.       $sr = New-Object -TypeName System.IO.StreamReader -ArgumentList $gzipstream, ([System.Text.Encoding]::UTF8)
  47.    
  48.       $match = $recontent.Match($sr.ReadToEnd())
  49.       if ($match.Success) {
  50.         Write-Verbose "Match $_ success"
  51.         $xmldoc.LoadXml(($rejs.Replace($match.Value, '') -replace '<([^\x00-\x7e]+)>', '&lt;$1&gt;'))
  52.         $strbuilder.Length = 0
  53.         # word-cont
  54.         [void]$strbuilder.Append($xmldoc.SelectSingleNode('//h1[@class="keyword"]/text()').Value).Append("`t")
  55.         # dict-translation
  56.         [void]$strbuilder.Append( ($xmldoc.SelectNodes('//ul/li[position()<last()]') | ForEach-Object { $_.innerText }) -join " " ).Append("`t")
  57.         try {
  58.           # dict-chart
  59.           $strjson = [System.Web.HttpUtility]::UrlDecode($xmldoc.SelectSingleNode('//div[@id="dict-chart-basic"]/@data').Value)
  60.           $jsobj = [Microsoft.JScript.Eval]::JScriptEvaluate("($strjson)", $vsaengine )
  61.           foreach ($field in $jsobj) {
  62.             [void]$strbuilder.Append($jsobj.Item($field).Item('sense')).Append(':').Append($jsobj.Item($field).Item('percent')).Append(',')
  63.           }
  64.           [void]$strbuilder.Remove($strbuilder.Length - 1, 1)
  65.         }
  66.         catch {
  67.           # $_ | Out-String | Write-Host -ForegroundColor Red
  68.         }
  69.         # output result string
  70.         $sw.WriteLine(($strbuilder.ToString() -replace "[\r\n]"))
  71.         # $strbuilder.ToString()|Out-Host
  72.       }
  73.       else {
  74.         Write-Verbose "Match $_ failed"
  75.       }
  76.     }
  77.     catch {
  78.       $_ | Out-String | Write-Host -ForegroundColor Red  
  79.     }
  80.     finally {
  81.       $readstream.Close()
  82.       Remove-Variable readstream
  83.       if ($gzipstream) {
  84.         $gzipstream.Dispose()
  85.       }
  86.       if ($sr) {
  87.         $sr.Dispose()
  88.       }
  89.     }
  90.   }
  91.   else {
  92.     $sw.WriteLine($_)
  93.   }
  94. } -End {
  95.   $sw.Dispose()
  96.   $webclient.Dispose()
  97. }
复制代码

作者: qixiaobin0715    时间: 2019-8-29 18:07

回复 15# flashercs
测试成功!但存在一些小问题,有些单词未提取出来。分三种情况:
1.大多数属于单词本身在词典中不存在“分布图”,并且提示错误,结果中忽略。如fines、cavalry、GDP等
2.不存在分布图,运行未提示错误,直接忽略。如baseman。是释义中的括号造成的吗?
3.有“分布图”,直接忽略。不知什么情况。有这样几个单词:
  1. in-depth
  2. storytelling
  3. same-sex
  4. high-end
  5. sweaty
  6. first-time
  7. president-elect
复制代码
请帮忙给看看。能否这样解决:
1.释义和分布图内容之间用制表符分隔。
2.对于第1、2条的问题,在提取结果中条目只列出单词和释义。
3.第3条出了什么问题,能否解决。
作者: flashercs    时间: 2019-8-29 20:24

回复 16# qixiaobin0715


    你什么Windows系统?不太敢用htmldom,win7与win10对html兼容性差别很大
作者: terse    时间: 2019-8-29 20:49

本帖最后由 terse 于 2019-8-29 22:53 编辑

这样可以吗
  1. @set @i=0 /* & @echo off & >提取结果.txt cscript.exe -NoLogo -E:JScript %0 <单词列表.txt & pause exit  */
  2. var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
  3. function GetContent(url) {
  4.         xmlhttp.open("GET", url ,false);
  5.         xmlhttp.send();
  6.         return(xmlhttp.responseText);
  7. };
  8. while (!WSH.StdIn.AtEndOfStream) {
  9.       var str = WSH.StdIn.ReadLine();
  10.       if (str) {
  11.            var url = "http://dict.cn/" + str;
  12.            var html = new ActiveXObject("htmlfile");
  13.            html.write(GetContent(url));
  14.            var t = html.getElementsByTagName("ul")[0];
  15.            if (t) {
  16.                str += "\t" + t.innerText.replace(/[\r\n]/gm,'') + "。\t";
  17.                if (html.getElementById("dict-chart-basic")) {
  18.                    var obj = new Function("return" + unescape(html.getElementById("dict-chart-basic").data))();
  19.                    for(var key in obj ){  str += obj[key].percent > 5 ? obj[key].sense + ":"+ obj[key].percent + "%, " : ""};
  20.                }
  21.            };
  22.            else { str += "\t" + "错误" };
  23.            WSH.Echo(str);
  24.      };
  25. };
复制代码

作者: qixiaobin0715    时间: 2019-8-29 21:49

回复 17# flashercs

单位的电脑是Windows7,家里的是Windows10.最好能在单位用,家里用也可。
作者: qixiaobin0715    时间: 2019-8-29 21:55

回复 18# terse
因为有些单词不存在分布图信息,可能会产生错误。
你的代码测试后发现,遇到不含分布图的单词会闪退。比如单词railway就没有分布图信息。单词列表:
good
railway
big
闪退后,只有good的信息能够提取出来。
作者: flashercs    时间: 2019-8-29 22:04

回复 20# qixiaobin0715


    已修改代码,请测试,支持win7和win10
作者: qixiaobin0715    时间: 2019-8-29 22:21

回复 21# flashercs

完全符合要求,很好用。
作者: terse    时间: 2019-8-29 22:54

回复 20# qixiaobin0715
加了一个判断
作者: qixiaobin0715    时间: 2019-8-29 23:06

回复 23# terse
测试成功!谢谢!
作者: qixiaobin0715    时间: 2019-8-29 23:08

这里一并感谢所有关注的人。谢谢!
作者: qixiaobin0715    时间: 2019-8-30 08:45

回复 15# flashercs
测试中发现了个小问题,海词查不到的单词比如sauté,提示错误,结果中忽略。好修改的话,就麻烦了,结果中只列出单词即可。这种情况不多,要是太麻烦了就算了。
作者: flashercs    时间: 2019-8-30 13:07

回复 26# qixiaobin0715

本来就有错误提示啊,结果也忽略了,你的意思是怎么修改?
作者: qixiaobin0715    时间: 2019-8-30 13:53

回复 27# flashercs
查不到的单词在结果文本中也占一行,此行只显示单词即可。
作者: qixiaobin0715    时间: 2019-8-30 14:38

回复 27# flashercs
算了,怪麻烦的,就这样吧。谢谢了
作者: flashercs    时间: 2019-8-30 19:44

回复 29# qixiaobin0715


    已修改了,主要是没明白你的要求!
作者: qixiaobin0715    时间: 2019-8-31 09:08

回复 30# flashercs
有提示错误信息,列出来查不到的单词,完美。谢谢了,下次合作愉快!
作者: qixiaobin0715    时间: 2019-9-3 12:29

回复 15# flashercs
提取时有发现两个问题。
1.下面的单词提取不到内容:
  1. do
  2. one
  3. order
  4. mine
  5. communicate
  6. guarantee
  7. operator
  8. steep
  9. abstract
  10. diabetes
复制代码
2.下面单词提取内容占据两行或三行:
  1. than
  2. steady
  3. psychologist
  4. export
  5. Korean
复制代码
请给看看是哪里的问题!
作者: flashercs    时间: 2019-9-3 14:29

回复 32# qixiaobin0715


    修复了第一个问题。
第二个问题是你记事本打开了自动换行。。。。。
作者: qixiaobin0715    时间: 2019-9-3 16:00

回复 33# flashercs
win7
不是自动换行,而是存在换行符。
作者: flashercs    时间: 2019-9-3 19:48

回复 34# qixiaobin0715


   已修改
作者: qixiaobin0715    时间: 2019-9-3 20:11

回复 35# flashercs

辛苦了,谢谢!!!
作者: qixiaobin0715    时间: 2019-11-6 17:27

回复 35# flashercs

在前面的基础上增加提取例句内容:
1.例句放在最后,与前面内容用制表符隔开;
2.只需提取各个词性的前两个例句,若只有一个例句就提取一个,“查看更多”中的例句不需提取;
3.换行用<br>表示。
4.比如提取单词big,网页中例句形式显示如图,提取格式如下
  1. big adj.大的;重要的;有雄心的;受欢迎的;adv.宏大地;夸大地;成功地;n.杰出的组织和个人 大的:71,重要的:11,夸大地:5,成功地:5,受欢迎的:4,杰出的组织和个人:2,宏大地:1,有雄心的:1 用作形容词 (adj.)<br>1.New York is a big commercial city.<br>纽约是一座大的商业城市。<br>2.His business yields big profits.<br>他的生意带来巨大的利润。<br>3.Don't cry, you are a big boy now.<br>别哭,你现在已经是大男孩了。<br>4.The big moment has come at last!<br>重要的时刻终于到来了!<br>5.The big thing is that you know what you want.<br>重要的是你必须知道自己想要什么。<br>6.He's got a lot of big ideas about how to change the system.<br>就如何改变体制,他有一些远大的想法。<br>7.That rock and roll band is very big in Chicago.<br>那个摇滚乐团在芝加哥很受欢迎。<br> 用作副词 (adv.)<br>1.You need to think big(= aim to achieve a lot).<br>你要敢想。<br>2.As for us, we mustn't talk big in our external propaganda.<br>在我们自己方面,对外宣传不要夸大。<br>3.The band comes over big with pop fans.<br>该乐队受流行音乐歌迷欢迎大为成功。<br> 用作名词 (n.)  <br>1.With that new promotion he's now one of the bigs in the company.<br>通过那次得晋升,他现在是公司的杰出员工之一。
复制代码
也即是按下面格式提取:
前面提取内容        用作形容词(adj.)<br>1.第一个例句<br>译文<br>2.第二个例句<br>译文<br>用作副词(adv.)<br>...<br>用作名词(n.)<br>1.第一个例句<br>译文
希望您给予帮助,另有酬谢。
作者: qixiaobin0715    时间: 2019-11-7 09:56

回复 38# flashercs

挺棒的!
经过测试,还有点小问题及要求:
1.下列单词提取时,有错误提示,例句未能提取:
  1. African-American
  2. CEO
  3. ie
  4. allegation
  5. annually
  6. anyone
  7. boyfriend
  8. businessman
  9. celebration
  10. Christianity
  11. courtroom
  12. educator
  13. girlfriend
  14. Hispanic
  15. incredibly
  16. initially
  17. Iraqi
  18. Israeli
  19. Jewish
  20. juror
  21. longtime
  22. mainstream
  23. obviously
  24. originally
  25. oversee
  26. Palestinian
  27. pastor
  28. playoff
  29. PM
  30. precisely
  31. publisher
  32. rebuild
  33. regularly
  34. reportedly
  35. significantly
  36. tablespoon
  37. teammate
  38. typically
  39. ultimately
  40. workplace
  41. yeah
复制代码
2.网页上本身没有释义度分布图的单词,释义和例句之间直接用制表符分隔,能否增加一个制表符,后续处理需要相同的部分对齐。
现在提取出来的形式是:
  1. PC abbr.个人计算机(=personal computer) <br>1.Maintenance of PC is in my element.<br>我对电脑的维修保养很在行。
复制代码
需要的格式是:
  1. PC abbr.个人计算机(=personal computer) <br>1.Maintenance of PC is in my element.<br>我对电脑的维修保养很在行。
复制代码

作者: flashercs    时间: 2019-11-7 14:23

本帖最后由 flashercs 于 2019-11-9 11:08 编辑
  1. <#*,:&cls
  2. @echo off
  3. pushd "%~dp0"
  4. Powershell -NoProfile -ExecutionPolicy RemoteSigned -Command ". ([ScriptBlock]::Create((Get-Content -LiteralPath \"%~0\" -ReadCount 0 | Out-String ))) "
  5. popd
  6. pause
  7. exit /b
  8. #>
  9. $VerbosePreference = "Continue"
  10. $inputFile = "单词列表.txt"
  11. $outputFile = "结果.txt"
  12. Get-Content -LiteralPath $inputFile -OutBuffer 100 | ForEach-Object -Begin {
  13.   $sw = New-Object -TypeName System.IO.StreamWriter -ArgumentList $outputFile, $false, ([System.Text.Encoding]::Default), 65536
  14.   # webclient settings
  15.   $webclient = New-Object -TypeName System.Net.WebClient
  16.   $webclient.BaseAddress = 'http://dict.cn/'
  17.   $webclient.Encoding = [System.Text.Encoding]::UTF8
  18.   $webclient.Headers.Add("Accept", "text/html, application/xhtml+xml, application/xml; q=0.9, */*; q=0.8")
  19.   $webclient.Headers.Add("Accept-Encoding", "gzip")
  20.   $webclient.Headers.Add("Accept-Language", "en-US, en; q=0.8, zh-Hans-CN; q=0.5, zh-Hans; q=0.3")
  21.   # xml parser
  22.   $xmldoc = New-Object -TypeName System.Xml.XmlDocument
  23.   # re
  24.   $remain = [regex]'(?si)<div\s+class="main"[^>]*>.*?(?=<div\s+class="righter")'
  25.   # $recontent = [regex]'(?si)<div\s+class="word"[^>]*>.*?(?=<div\s+class="section[^"]*"[^>]*>)'
  26.   $rejs = [regex]'(?si)<script[^>]*>.*?</script>'
  27.   # $resent = [regex]'(?si)(?<=<h3[^>]*>例句</h3>).*?(?=<h3)'
  28.   $reXMLEntities = [regex]'(?si)&[^;<]*(;|(?=<|$))'
  29.   $evaluator = {
  30.     param($m)
  31.     $s = $m.Value;
  32.     if ($m.Groups[1].Value -eq '') {
  33.       $s += ';'
  34.     }
  35.     [System.Web.HttpUtility]::HtmlEncode([System.Web.HttpUtility]::HtmlDecode($s))
  36.   } -as [System.Text.RegularExpressions.MatchEvaluator]
  37.   # stringbuilder
  38.   $strbuilder = New-Object -TypeName System.Text.StringBuilder
  39.   Add-Type -AssemblyName System.Web.Extensions
  40.   $JSON = New-Object -TypeName System.Web.Script.Serialization.JavascriptSerializer -ErrorAction Stop
  41.   # $vsaengine = [Microsoft.JScript.Vsa.VsaEngine]::CreateEngine()
  42.   Add-Type -AssemblyName System.Web
  43. } -Process {
  44.   Write-Verbose "Fetching $_ ..."
  45.   for ($i = 2; $i -ge 0; $i--) {
  46.     try {
  47.       $readstream = $webclient.OpenRead($_)
  48.       Write-Verbose "Fetch $_ success"
  49.       break
  50.     } catch {
  51.       $_ | Out-String | Write-Host -ForegroundColor Red
  52.     }
  53.   }
  54.   if ($readstream) {
  55.     try {
  56.       $gzipstream = New-Object -TypeName System.IO.Compression.GZipStream -ArgumentList $readstream, ([System.IO.Compression.CompressionMode]::Decompress)
  57.       $sr = New-Object -TypeName System.IO.StreamReader -ArgumentList $gzipstream, ([System.Text.Encoding]::UTF8)
  58.       $strhtml = $sr.ReadToEnd()
  59.       $match = $remain.Match($strhtml)
  60.       # div.main matched
  61.       if ($match.Success) {
  62.         Write-Verbose "Match $_ success"
  63.         # convert html to xml
  64.         $strxml = $rejs.Replace($match.Value, '') -replace '(?s)<!--.*?-->' -replace '<([^\x00-\x7e]+)>', '&lt;$1&gt;' -replace '<br>', '<br/>'
  65.         $strxml = $reXMLEntities.Replace($strxml, $evaluator)
  66.         $xmldoc.LoadXml($strxml)
  67.         $strbuilder.Length = 0
  68.         $nodeWord = $xmldoc.DocumentElement.SelectSingleNode('div[@class="word"]')
  69.         # word-cont
  70.         [void]$strbuilder.Append($nodeWord.SelectSingleNode('.//h1[@class="keyword"]/text()').Value).Append("`t")
  71.         # dict-translation
  72.         [void]$strbuilder.Append( ($nodeWord.SelectNodes('.//ul/li[position()<last()]') | ForEach-Object { $_.innerText }) -join " " ).Append("`t")
  73.         # dict-chart
  74.         $nodeChartBasic = $nodeWord.SelectSingleNode('.//div[@id="dict-chart-basic"]/@data')
  75.         # chart basic exist
  76.         if ($nodeChartBasic) {
  77.           $strjson = [System.Uri]::UnescapeDataString($nodeChartBasic.Value)
  78.           $jsobj = $JSON.DeserializeObject($strjson)
  79.           foreach ($field in $jsobj.Keys) {
  80.             [void]$strbuilder.Append($jsobj.Item($field).Item('sense')).Append(':').Append($jsobj.Item($field).Item('percent')).Append(',')
  81.           }
  82.           [void]$strbuilder.Remove($strbuilder.Length - 1, 1)
  83.         }
  84.         [void]$strbuilder.Append("`t")
  85.         
  86.         # 例句
  87.         # $match1 = $resent.Match($strhtml)
  88.         $nodeSent = $xmldoc.DocumentElement.SelectSingleNode('div[@class="section sent"]/h3[text()="例句"]/following-sibling::div')
  89.         if ($nodeSent) {
  90.           try {
  91.             # $xmldoc.LoadXml(($match1.Value -replace '<br>', '<br/>' -replace '<([^\x00-\x7e]+)>', '&lt;$1&gt;'))
  92.             $nodeSent.SelectNodes('ol') | ForEach-Object {
  93.               # 用作形容词 (.adj)
  94.               [void]$strbuilder.Append(($_.PreviousSibling.InnerText -replace '\s+' -replace '\(', ' $&')).Append('<br>')
  95.               $_.SelectNodes('li[position()<3]') | ForEach-Object -Begin { $index = 0 } -Process {
  96.                 $index++;
  97.                 [void]$strbuilder.Append("$index.$(($_.SelectNodes('text()')|ForEach-Object {$_.Value}) -join '<br>')").Append('<br>')
  98.               }
  99.             }
  100.             [void]$strbuilder.Remove($strbuilder.Length - 4, 4)
  101.           } catch {
  102.             $_ | Out-String | Write-Host -ForegroundColor Red
  103.           }
  104.         } else {
  105.           Write-Verbose "没有例句."
  106.         }
  107.         # output result string
  108.         $sw.WriteLine(($strbuilder.ToString() -replace "[\r\n]+"))
  109.       } else {
  110.         Write-Verbose "Match $_ failed"
  111.       }
  112.     } catch {
  113.       $_ | out-string | Write-Host -ForegroundColor Red
  114.     } finally {
  115.       $readstream.Close()
  116.       Remove-Variable readstream
  117.       if ($gzipstream) {
  118.         $gzipstream.Dispose()
  119.       }
  120.       if ($sr) {
  121.         $sr.Dispose()
  122.       }
  123.     }
  124.   } else {
  125.     $sw.WriteLine($_)
  126.   }
  127. } -End {
  128.   $sw.Dispose()
  129.   $webclient.Dispose()
  130. }
复制代码

作者: qixiaobin0715    时间: 2019-11-7 16:13

回复 39# flashercs

已扫码。
极少部分单词出现问题,显示源页面,并且提取不到。比如:face,contact,confront,encounter等。
作者: flashercs    时间: 2019-11-8 17:10

回复 40# qixiaobin0715


    改
作者: terse    时间: 2019-11-8 17:47

怎么这么复杂呢 混编的也行吧
  1. @set @i=0 /* & @echo off & cscript.exe -NoLogo -E:JScript %0 <单词列表.txt >结果.txt& pause & exit */
  2. var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
  3. function GetContent(url) {
  4.         xmlhttp.open("GET", url ,false);
  5.         xmlhttp.send();
  6.         return(xmlhttp.responseText);
  7. };
  8. function getByClass(tag,Classname){
  9.         if(html.getElementsByClassName){
  10.                 return html.getElementsByClassName(Classname);
  11.         }
  12.         var tags = html.getElementsByTagName(tag);
  13.         for(var i = 0,len = tags.length; i < len; i++){
  14.                 if( tags[i].className ==Classname){
  15.                          return(tags[i]);
  16.                 }
  17.         }
  18. }
  19. while (!WSH.StdIn.AtEndOfStream) {
  20.         var s = WSH.StdIn.ReadLine();
  21.         var str = s;
  22.         var url = "http://dict.cn/" + str;
  23.         var html = new ActiveXObject("htmlfile");
  24.         html.write(GetContent(url));
  25.         var ul = getByClass("ul","dict-basic-ul");
  26.         if (ul) {
  27.                 str += "\t" + ul.innerText.replace(/[\r\n]/gm,'') + "。\t"
  28.                 if (html.getElementById("dict-chart-basic")) {
  29.                         var obj = new Function("return" + unescape(html.getElementById("dict-chart-basic").data))();
  30.                         for(var key in obj ) { str += obj[key].percent > 5 ? obj[key].sense + ":"+ obj[key].percent + "%, " : ""};
  31.                 };
  32.                 var div = getByClass("div","layout sort");
  33.                 if (div) {
  34.                         str+= '\t'
  35.                         var b = div.getElementsByTagName("b");
  36.                         var ol = div.getElementsByTagName("ol");
  37.                         for (var i=0; i<ol.length; i++) {
  38.                                 var s =b[i];
  39.                                 if (s) { str+= s.innerText + '<br>' };
  40.                                 var li= ol[i].getElementsByTagName("li");
  41.                                 for (var j=0, len = li.length; j<len; j++) {
  42.                                         if (j < 2) {str+= j+1 + '. ' + li[j].innerText + '<br>' };
  43.                                 };
  44.                         };
  45.                         WSH.Echo(str.replace(/\r?\n/g,'<br>'));
  46.                 };
  47.        };
  48.        else { str += "\t" + "错误" };
  49. };
复制代码

作者: qixiaobin0715    时间: 2019-11-8 21:34

回复 41# flashercs

完美!!!
作者: qixiaobin0715    时间: 2019-11-8 21:37

回复 42# terse

不错。就是速度稍慢,少部分单词漏提。
作者: qixiaobin0715    时间: 2019-11-8 22:20

回复 38# qixiaobin0715

提取的文件增加制表符对齐相同内容问题,用文本编辑器打开,用正则表达式替换已解决。
作者: terse    时间: 2019-11-8 23:11

回复 44# qixiaobin0715
把漏提的发上来 看看什么问题
作者: qixiaobin0715    时间: 2019-11-9 09:03

回复 46# terse

未能提取的是一些不存在释义常用度分布图的单词,我还是需要提取释义和例句。如:
  1. do
  2. one
  3. order
  4. mine
  5. communicate
  6. guarantee
  7. operator
复制代码

作者: terse    时间: 2019-11-9 10:02

回复 47# qixiaobin0715
将25行 改为下面的试
  1. var ul = getByClass("div","basic clearfix");
复制代码

作者: terse    时间: 2019-11-9 10:19

修正一下
  1. @set @i=0 /* & @echo off & cscript.exe -NoLogo -E:JScript %0 <单词列表.txt >结果.txt& pause & exit */
  2. var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
  3. function GetContent(url) {
  4.         xmlhttp.open("GET", url ,false);
  5.         xmlhttp.send();
  6.         return(xmlhttp.responseText);
  7. }
  8. function getByClass(tag,Classname){
  9.         if(html.getElementsByClassName){
  10.                 return html.getElementsByClassName(Classname);
  11.         }
  12.         var tags = html.getElementsByTagName(tag);
  13.         for(var i = 0,len = tags.length; i < len; i++){
  14.                 if( tags[i].className ==Classname){
  15.                          return(tags[i]);
  16.                 }
  17.         }
  18. }
  19. while (!WSH.StdIn.AtEndOfStream) {
  20.         var s = WSH.StdIn.ReadLine();
  21.         var str = s;
  22.         var url = "http://dict.cn/" + str;
  23.         var html = new ActiveXObject("htmlfile");
  24.         html.write(GetContent(url));
  25.         try {
  26.                 var ul = getByClass("div","basic clearfix");
  27.                 str += "\t" + ul.innerText.replace(/[\r\n]/gm,'') + "。\t";
  28.                 if (html.getElementById("dict-chart-basic")) {
  29.                         var obj = new Function("return" + unescape(html.getElementById("dict-chart-basic").data))();
  30.                         for(var key in obj ) { str += obj[key].percent > 5 ? obj[key].sense + ":"+ obj[key].percent + "%, " : ""};
  31.                 }
  32.                 var div = getByClass("div","layout sort");
  33.                 if (div) {
  34.                         str+= '\t'
  35.                         var b = div.getElementsByTagName("b");
  36.                         var ol = div.getElementsByTagName("ol");
  37.                         for (var i=0; i<ol.length; i++) {
  38.                                 var s =b[i];
  39.                                 if (s) { str+= s.innerText + '<br>' };
  40.                                 var li= ol[i].getElementsByTagName("li");
  41.                                 for (var j=0, len = li.length; j<len; j++) {
  42.                                         if (j < 2) {str+= j+1 + '. ' + li[j].innerText + '<br>' };
  43.                                 }
  44.                         }
  45.                 }
  46.        }
  47.         catch (e) {str += "\t" + "错误"};
  48.         WSH.Echo(str.replace(/\r?\n/g,'<br>'));
  49. }
复制代码

作者: flashercs    时间: 2019-11-9 11:27

回复 45# qixiaobin0715


    先前我对制表符理解有误,是需要4列数据吧?已修改。
作者: qixiaobin0715    时间: 2019-11-9 13:18

两位大神给出的代码提取结果均符合我期望的结果。谢谢!!!




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2