以文本方式查看主题

-  Foxtable(狐表)  (http://foxtable.net/bbs/index.asp)
--  专家坐堂  (http://foxtable.net/bbs/list.asp?boardid=2)
----  [求助]为什么指定行可以采集面循环表就不行  (http://foxtable.net/bbs/dispbbs.asp?boardid=2&id=187290)

--  作者:bohe
--  发布时间:2023/7/6 9:09:00
--  [求助]为什么指定行可以采集面循环表就不行
    Dim r As Row = Tables("成绩").Rows(1)

    stuKsh = r("考生号")
    stuPass = r("身份证号后四位")
    Functions.Execute("btn1") \'登录网页采集数据
    
MessageBox.Show("完成")

以上代码可以完成,可改成下面的就不行,只能采集到最后一行表的数据,还没结束最后的提示早早就出来了。

For Each r As Row In Tables("成绩").Rows
  
    stuKsh = r("考生号")
    stuPass = r("身份证号后四位")
    Functions.Execute("btn1") \'登录网页采集数据
    
Next

MessageBox.Show("完成")

--  作者:有点蓝
--  发布时间:2023/7/6 9:14:00
--  
函数里有什么代码?
--  作者:bohe
--  发布时间:2023/7/6 9:30:00
--  
函数btn1

Dim web As System.Windows.Forms.WebBrowser = Forms("窗口1").Controls("WebBrowser1").BaseControl
web.Navigate("http://gkcf.jxedu.gov.cn/")
Do Until web.ReadyState = 4
    Application.DoEvents
Loop
web.Document.GetElementById("key1").SetAttribute("value", stuKsh)
web.Document.GetElementById("key2").SetAttribute("value", stuPass)

Dim imghtml As Object = web.Document.GetElementsByTagName("img") \'获得当前页面的img标签HTML元素集合
Dim base64 As String = imghtml(1).getattribute("src")
Dim bytes As Byte() = Convert.FromBase64String(base64.Substring(base64.IndexOf(",") + 1)) \'获取图片的base64码值

Dim str = myocr(bytes, bytes.Length) \'获取验证码

Dim inputhtml As System.Windows.Forms.HtmlElementCollection = web.Document.GetElementsByTagName("input") \'获得当前页面的input标签HTML元素集合
For i As Integer = 0 To inputhtml.Count - 1 \'循环所有input标签
    If inputhtml(i).OuterHtml.Contains("验证码(不分大小写)") Then \'判断该input标签是否包含这个字符串(如果包含说明该input标签是验证码输入框)
        inputhtml(i).SetAttribute("value", str)
        Exit For
    End If
Next

    web.Document.GetElementById("btncx").InvokeMember("click") \'点击查询按键

Forms("窗口1").TimerEnabled = True
Forms("窗口1").TimerInterval = 1000

计时器代码 Functions.Execute("btn2")

函数btn2

Forms("窗口1").TimerEnabled = False
Dim web As System.Windows.Forms.WebBrowser = Forms("窗口1").Controls("WebBrowser1").BaseControl
Dim divhtml As System.Windows.Forms.HtmlElementCollection = web.Document.GetElementsByTagName("div") \'获得当前页面的div标签HTML元素集合
For i As Integer = 0 To divhtml.Count - 1 \'循环所有div标签
    If divhtml(i).OuterHtml.Contains("myTabContent") Then \'myTabContent是成功登录后数据表的id
        Dim trhtml As Object = web.Document.GetElementById("total").GetElementsByTagName("tr") \'获得当前页面的id为total下的标签tr元素集合
        Dim tdhtml 
        Dim KeMu As New List(Of String) From {"语文成绩", "数学成绩", "外语成绩", "物理成绩", "化学成绩", "生物成绩", "政治成绩", "历史成绩", "地理成绩", "综合成绩", "本科总分(含加分)", "本科分平行排名"} \'定义网页需采集的数据集合
        Dim XueKe As New List(Of String) From {"语文", "数学", "外语", "物理", "化学", "生物", "政治", "历史", "地理", "综合", "总分", "总分排名"} \'定义成绩表里的字段集合
        Dim xkstr, cjstr As String
        Dim h As Integer
        Dim r As Row
        \'采集网页数据到数据表
        For j As Integer = 1 To trhtml.count - 1
            xkstr = trhtml(j).GetElementsByTagName("td")(0).innertext
            cjstr = trhtml(j).GetElementsByTagName("td")(1).innertext
            If KeMu.Contains(xkstr) AndAlso cjstr IsNot Nothing Then
                xkstr = xueke(KeMu.IndexOf(xkstr))
                h = Tables("成绩").FindRow("[考生号] = " & stuKsh)
                r = Tables("成绩").Rows(h)
                r(xkstr) = cjstr
            End If 
        Next
        CaiJi = True
        Exit For
    End If
\'以下是消除验证码出错弹出的提示框
    If divhtml(i).OuterHtml.Contains("wintips") And divhtml(i).OuterHtml.Contains("display: block;") Then \'判断该input标签是否包含这个字符串(如果包含说明该div标签是在弹窗里)
        \'MessageBox.Show(divhtml(i).OuterHtml)
        \'messagebox.Show(divhtml(i).Children(1).OuterHtml)
        divhtml(i).Children(1).InvokeMember("click")
        Sleep(1000)
        Functions.Execute("btn1")
        Exit For
    End If
Next

--  作者:有点蓝
--  发布时间:2023/7/6 9:34:00
--  
把数据作为参数传入函数,不要使用全局变量,去掉全局变量

函数btn1
dim stuKsh  as string = args(0)
dim stuPass as string = args(1)
Dim web As System.Windows.Forms.WebBrowser = Forms("窗口1").Controls("WebBrowser1").BaseControl
web.Navigate("http://gkcf.jxedu.gov.cn/")
Do Until web.ReadyState = 4

……
按钮
For Each r As Row In Tables("成绩").Rows
    Functions.Execute("btn1",r("考生号"),r("身份证号后四位")) \'登录网页采集数据
Next

--  作者:bohe
--  发布时间:2023/7/6 9:42:00
--  
不用全局变量的话,如果验证码出错,函数btn2消除提示框后要调用函数btn1重新登录,这样无法传参
--  作者:有点蓝
--  发布时间:2023/7/6 10:02:00
--  
建议改一下处理逻辑,不要使用循环。使用全局变量记录当前行

publish n as integer

1、处理第一行,比如
n = 0
Dim r As Row = Tables("成绩").Rows(n)
2、开启计时器
3、计时器处理完毕,处理下一行,比如
n = n+1
Dim r As Row = Tables("成绩").Rows(n)
4、重复2、3

--  作者:bohe
--  发布时间:2023/7/6 10:11:00
--  
蓝版,你这个我等下就试一下,刚才做了个简单试验,发现我之前的逻辑受计时器影响有问题

函数test1

Output.Show("函数1")
Forms("窗口2").TimerEnabled = True
Forms("窗口2").TimerInterval=1000

计时器代码 Functions.Execute("test2")

函数test2

Forms("窗口2").TimerEnabled = False
Output.Show("函数2")

命令窗口代码
For i As Integer = 1 To 3
    Output.Show(i)
    Functions.Execute("test1")
Next
Output.Show("结束")

运行结果是:
1
函数1
2
函数1
3
函数1
结束
函数2

看来用循环确实不行



--  作者:bohe
--  发布时间:2023/7/6 11:12:00
--  
谢谢蓝版,按你这个思路成功了!图片点击可在新窗口打开查看图片点击可在新窗口打开查看图片点击可在新窗口打开查看
[此贴子已经被作者于2023/7/6 11:12:30编辑过]