搜索
查看: 4944|回复: 3

对称式协程coroutine实际使用中遇到的问题请教

[复制链接]

48

主题

593

帖子

3336

积分

五级会员

Rank: 8Rank: 8

积分
3336
发表于 2013-1-3 13:26:49 | 显示全部楼层 |阅读模式
本帖最后由 jyb21 于 2013-1-3 21:56 编辑

参考范例 对称式协程演示 修改了一下 想将其用于实现: 提取网址->采集内容 ->内容入库 这样的一个流程,
试验过程中遇到的问题如截图所示:
错误.jpg
目前流程只能取到一个网址运行到获取采集的标题和内容 然后就会出现 全部协程已结束、分派控制权限失败。
按设想正确情况下,数据库中的接近20条网址,应该是逐个取出网址,获取标题和内容后 存入数据库 这样的流程。
请了解的帮助诊断一下,谢谢。
源码如下:
  1. import web.form;
  2. import sqlite;
  3. import myTools;
  4. /*DSG{{*/
  5. mainForm = ..win.form( bottom=400;parent=...;text="aardio Form";right=600;scroll=1 )
  6. mainForm.add(
  7. button={ bottom=48;right=540;left=460;top=15;z=2;text="采集";cls="button" };
  8. static={ bottom=233;right=586;left=14;top=52;transparent=1;z=1;cls="static" };
  9. lstInfo={ bgcolor=16777215;bottom=391;right=591;left=9;
  10. items={  };z=3;top=241;edge=1;cls="listbox" }
  11. )
  12. /*}}*/

  13. //创建web窗体
  14. mainWb = web.form( mainForm.static
  15.         ,//可输入_UIFLAG_ 前缀的常量自定义外观
  16.         ,//可输入_DLCTL_ 前缀的常量以控制下载行为
  17.         ,//"USER AGENT"
  18.         );

  19. mainWb.NewWindow2=function( ppDisp, Cancel) {  
  20.     return mainWb.openproxy/*创建代理窗口捕获网址并在当前窗口打开*/  
  21. }
  22. mainWb.noScriptErr=true;
  23. mainForm.show();

  24. mainWb.go("http://ask.yaolan.com/")
  25. mainWb.wait("");//等待指定网址,可以使用模式匹配语法

  26. //对称式协程演示
  27. import coroutine;

  28. //逐个提取url地址
  29. queryUrl = function( taskIdArg = 0 ){
  30.         spiderContentTask = coroutine.create(spiderContent)
  31.         insertSqliteTask = coroutine.create(insertSqlite)
  32.         sqlConn = sqlite("\db.db")
  33.         //迭代方式查询数据
  34.         for url in sqlConn.each("select  * from spiderUrl where taskId != "+taskIdArg/*+" limit 0,10"*/ ) {
  35.                 sqlConn.exec(  "UPDATE spiderUrl SET taskId="+taskIdArg+" WHERE eurl='" + url +"'")  
  36.                 sleep( 1000 );
  37.                 coroutine.transfer(spiderContentTask,url)
  38.         }  
  39.         //关闭数据库连接  
  40.         sqlConn.close()
  41. }  
  42.   
  43. //采集内容
  44. spiderContent = function(url){
  45.         io.open()
  46.         io.print(url)
  47.         htmlCode = myTools.decodeHtml(url);
  48.         for title,content in string.gmatch( htmlCode,'<@<h1>@>(.*?)<@</h1>@>.*?<@<div class="best_con_wz">@>(.*?)<@</div>@>') {
  49.                 io.print(title,content)
  50.                 coroutine.transfer(insertSqliteTask,title,content)
  51.         }
  52. }

  53. //采集网址插入数据库
  54. insertSqlite = function(title,content) {
  55.         var sqlConn = sqlite("\db.db")
  56.         try {
  57.                 var re,err = sqlConn.exec( "create table spiderContent(etitle primary key,econtent,taskId integer);")
  58.         }
  59.         sqlConn.exec( "begin;" )  //开启事务
  60.         var count = 0;
  61.         coroutine.transfer(coroutine.main,3)
  62.         while(#title){         
  63.                 try{
  64.                         sql =  "replace into spiderContent values ('" + title +"','" + content +"',0);";
  65.                         sqlConn.exec( sql )
  66.                 }
  67.                 catch(e){
  68.                         io.print("插入url",url,"遇到错误",e)
  69.                 }
  70.                 coroutine.transfer(coroutine.main,3)
  71.                 sleep(0);               
  72.                 count++;
  73.                 if( count>10000 ){
  74.                         count = 0;
  75.                         sqlConn.exec( "commit;" );
  76.                         sqlConn.exec( "begin;" ) ;
  77.                 }
  78.         }
  79.         sqlConn.exec( "commit;" )  ;
  80.         sqlConn.close() ;
  81. }

  82. mainForm.button.oncommand = function(id,event){
  83.         coroutine.run(queryUrl,3)
  84. }

  85. mainForm.wndproc = function(hwnd,message,wparam,lparam){
  86.     select(message) {
  87.             //最小化到托盘
  88.         case( 0x112/*_WM_SYSCOMMAND*/ ){ //系统命令消息
  89.             if( wparam == 0xF020/*_SC_MINIMIZE*/ ){ //用户点击了最小化按钮
  90.                 import win.util.tray
  91.                 tray = win.util.tray(mainForm)
  92.                 mainForm.show(false);
  93.                 tray.message = 0x400+9981/*_WM_TRAYMESSAGE*/ //设置托盘图标回调消息
  94.                 return true;//阻击默认消息传递,取消最小化过程
  95.             }
  96.         }
  97.         //托盘点击事件
  98.         case (0x400+9981/*_WM_TRAYMESSAGE*/){
  99.             if(lparam=0x0202){
  100.                 mainForm.show(true)
  101.                 tray.delete()
  102.             }
  103.         }
  104.     }
  105. }
  106. //进入消息循环
  107. win.loopMessage();
复制代码
用于测试的完整工程文件如下:
学习测试.rar (4.67 KB, 下载次数: 21)
回复

使用道具 举报

4

主题

874

帖子

4704

积分

荣誉会员

Rank: 8Rank: 8

积分
4704
发表于 2013-1-3 16:13:03 | 显示全部楼层

把代码简化一下,先不要去读数据库, 简化一下代码,先搞懂协程怎么用。大家都很忙,没多少人有时间去分析全部代码。 友情提醒,勿喷!

把代码简化一下,先不要去读数据库,
简化一下代码,先搞懂协程怎么用。大家都很忙,没多少人有时间去分析全部代码。

友情提醒,勿喷!
回复

使用道具 举报

48

主题

593

帖子

3336

积分

五级会员

Rank: 8Rank: 8

积分
3336
 楼主| 发表于 2013-1-3 16:15:24 | 显示全部楼层

[quote][size=2][color=#999999]不争 发表于 2013-1-3 16:13[/color] [url=forum.php?mod=r

不争 发表于 2013-1-3 16:13
把代码简化一下,先不要去读数据库,
简化一下代码,先搞懂协程怎么用。大家都很忙,没多少人有时间去分析 ...

好的,还在测试 对称式 是怎样才算对称 还不太明白
回复

使用道具 举报

48

主题

593

帖子

3336

积分

五级会员

Rank: 8Rank: 8

积分
3336
 楼主| 发表于 2013-1-6 21:10:43 | 显示全部楼层

简化后的 可以直接测试的[code] import sqlite; //对称式协程演示 import coroutine; import win /

简化后的 可以直接测试的

  1. import sqlite;
  2. //对称式协程演示
  3. import coroutine;
  4. import win
  5. //获取网页返回值
  6. getHtml = function(url,postdata,referer){
  7.         return win.invoke(
  8.                 function(url,postdata,referer){
  9.                         import inet.http;
  10.                         http = inet.http();
  11.                         if(postdata){
  12.                                 html = http.post(url,postdata,,referer):"";
  13.                         }else {
  14.                                 html = http.get(url):"";
  15.                         }
  16.                         http.close();
  17.                         return html;
  18.                 },url,postdata,referer
  19.         )
  20. }
  21. //获取解码后的网页源文件
  22. decodeHtml = function(url){
  23.         html = getHtml(url);
  24.         if(html){
  25.                 html = string.fromto(html);
  26.         }
  27.         return html;
  28. }

  29. //逐个提取url地址
  30. queryUrl = function( taskIdArg = 0 ){
  31.         spiderContentTask = coroutine.create(spiderContent)
  32.         insertSqliteTask = coroutine.create(insertSqlite)
  33.         tUrl = {"http://ask.yaolan.com/question/130106003519a804f9c2.html";"http://ask.yaolan.com/question/130105215839e2b13c89.html";"http://ask.yaolan.com/question/13010610204077a4acc1.html"}
  34.         for(k,v in tUrl){       
  35.                 coroutine.transfer(spiderContentTask,v)
  36.         }
  37. }  
  38. //采集内容
  39. spiderContent = function(url){
  40.         htmlCode = decodeHtml(url);
  41.         title,content = string.match( htmlCode,'<@<h1>@>(.*?)<@</h1>@>.*?<@<div class="best_con_wz dotted_line">@>(.*?)<@<div class="best_spt_con clear">@>')
  42.         coroutine.transfer(insertSqliteTask,title,content)
  43. }
  44. //采集网址插入数据库
  45. insertSqlite = function(title,content) {
  46.         var sqlConn = sqlite("\db.db")
  47.         try {
  48.                 var re,err = sqlConn.exec( "create table spiderContent(etitle primary key,econtent,taskId integer);")
  49.         }
  50.         sqlConn.exec( "begin;" )  //开启事务
  51.         var count = 0;
  52.         io.open()
  53.         io.print(title,content)
  54.         //coroutine.transfer(coroutine.main,3)
  55.         while(#title){         
  56.                 try{
  57.                         sql =  "replace into spiderContent values ('" + title +"','" + content +"',0);";
  58.                         io.print(sql)
  59.                         sqlConn.exec( sql )
  60.                 }
  61.                 catch(e){
  62.                         io.print("插入url",url,"遇到错误",e)
  63.                 }
  64.                 //coroutine.transfer(coroutine.main,3)
  65.                 sleep(0);               
  66.                 count++;
  67.                 if( count>2 ){
  68.                         count = 0;
  69.                         sqlConn.exec( "commit;" );
  70.                         sqlConn.exec( "begin;" ) ;
  71.                 }
  72.                 io.print(count)
  73.                 coroutine.transfer(coroutine.main,3)
  74.         }
  75.         sqlConn.exec( "commit;" )  ;
  76.         sqlConn.close() ;
  77. }

  78. coroutine.run(queryUrl,3)

复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

手机版|未经许可严禁引用或转载本站文章|站长邮箱|aardio.com|aardio官方社区 ( 皖ICP备09012014号 )

GMT+8, 2018-12-18 01:53 , Processed in 0.078125 second(s), 25 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表