注册 登录
编程论坛 VFP论坛

老师好,这个网页的采集入口如何找,谢谢

jinanshui 发布于 2021-05-21 10:39, 3698 次点击
老师好,这个网页的采集入口如何找,谢谢
想把各个学校的序号,层次,专业类名称,选考科目范围,类中所含专业,采集到一个表中,
我们论坛原来讨论过这个问题,版主sdta老师,和红星二锅头老师也做过这个很成功的程序(链接如下),
https://bbs.bccn.net/thread-489091-1-1.html
但是现在这个网页的采集入口找不到了,请大家帮忙,谢谢,网址在下面
https://xkkm.
31 回复
#2
sdta2021-05-22 09:36
这种网页数据提取很费时间的
#3
jinanshui2021-05-22 09:39
回复 楼主 jinanshui
麻烦老师试试,老师我给您发短信了.
#4
吹水佬2021-05-22 10:27
这个页面好象是采用提交FORM数据来防盗链接,用浏览器控件来处理应该可行,如webbrowser
html文件可以动态创建载入,简单看看就是这样:
程序代码:
<!-- test.html -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <script>
        function ckxq(dm)
        {
            document.getElementById(dm).submit();
        }
    </script>
</head>
<body">
    <form id="10001" action="https://xkkm./xkkm/queryXxInfor" method="post" target="_blank">
    <input type="hidden" name="dm" value="10001">
    <input type="hidden" name="mc" value="%E5%8C%97%E4%BA%AC%E5%A4%A7%E5%AD%A6">
    <input type="hidden" name="yzm" value="ok">
    </form>
    <a href="#" onclick=ckxq("10001")>查看</a>
</body>
</html>

#5
jinanshui2021-05-22 11:13
回复 4楼 吹水佬
谢谢老师
#6
sdta2021-05-22 13:22
是不是这个结果
只有本站会员才能查看附件,请 登录
#7
sdta2021-05-22 14:06
只有本站会员才能查看附件,请 登录

全部数据将近20MB
#8
吹水佬2021-05-22 16:04
试试这个地址:北京大学,其他的改改应该也可以
https://xkkm.
#9
jinanshui2021-05-22 16:14
回复 7楼 sdta
是的,老师,是这个结果,谢谢
#10
sdta2021-05-22 16:19
完整数据:
只有本站会员才能查看附件,请 登录
#11
jinanshui2021-05-22 16:37
回复 10楼 sdta
老师,真是太厉害了
#12
吹水佬2021-05-23 15:18
有些学校的“类中所含专业”数据不完整
查看了源代码也有注释:<!-- 用jstl的fn标签库对传过来的专业中的'、'进行替换成<br/> -->
这部分数据只转存了254个字符,有缺失或有乱码字符
如:
只有本站会员才能查看附件,请 登录

只有本站会员才能查看附件,请 登录


#13
jinanshui2021-05-23 18:19
回复 12楼 吹水佬
谢谢,吹水佬老师的研究分析,我就观察不到.
#14
jinanshui2021-05-29 10:22
以下是引用吹水佬在2021-5-22 16:04:20的发言:

试试这个地址:北京大学,其他的改改应该也可以
https://xkkm.



老师,您是如何找到这个地址呢?谢谢
#15
吹水佬2021-05-29 15:28
以下是引用jinanshui在2021-5-29 10:22:39的发言:

老师,您是如何找到这个地址呢?谢谢

在 https://xkkm. 页面源码就看得到
只有本站会员才能查看附件,请 登录

4楼的代码就是参考这个改用绝对路径作为本地测试用
有点要注意的是:
页面源码的 mc=%E5%8C%97%E4%BA%AC%E5%A4%A7%E5%AD%A6 是一次编码
而链接地址的 mc=%25E5%258C%2597%25E4%25BA%25AC%25E5%25A4%25A7%25E5%25AD%25A6 是二次编码,也就是在一次编码后再次编码
编码示例:
程序代码:
mc = "北京大学"
? mc
bm1 = encodeURI(mc)
? "一次编码:"+bm1
bm2 = encodeURI(bm1)
? "二次编码:"+bm2
? "一次解码:"+decodeURI(bm2)
? "二次解码:"+decodeURI(decodeURI(bm2))
RETURN

FUNCTION encodeURI(cUnencoded)
    LOCAL jsCode, oSC
    TEXT TO jsCode TEXTMERGE NOSHOW PRETEXT 7
        function encode(unencoded)
        {
            return encodeURIComponent(unencoded).replace(/'/g,"%27").replace(/"/g,"%22");   
        }
    ENDTEXT
    oSC = CREATEOBJECT("ScriptControl")
    oSC.Language = "JavaScript"
    oSC.AddCode(jsCode)
    RETURN oSC.run("encode", cUnencoded)
ENDFUNC

FUNCTION decodeURI(cEncoded)
    LOCAL jsCode, oSC
    TEXT TO jsCode TEXTMERGE NOSHOW PRETEXT 7
        function decode(encoded)
        {
            return decodeURIComponent(encoded.replace(/\+/g,  " "));
        }
    ENDTEXT
    oSC = CREATEOBJECT("ScriptControl")
    oSC.Language = "JavaScript"
    oSC.AddCode(jsCode)
    RETURN oSC.run("decode", cencoded)
ENDFUNC

如果要了解页面的详细内容,可以使用“开发者工具”,现在大部份浏览器都有集成这个工具。
#16
sdta2021-05-29 15:38
mc = %  E5%  8C%  97%  E4%  BA%  AC%  E5%  A4%  A7%  E5%  AD%  A6
mc = %25E5%258C%2597%25E4%25BA%25AC%25E5%25A4%25A7%25E5%25AD%25A6
这个网页的二次编码只是骗骗外行人的,二次编码是在一次编码的基础上把"%"替换为"%25"即可,不需要进行二次编码
#17
吹水佬2021-05-29 15:57
以下是引用sdta在2021-5-29 15:38:57的发言:

mc = %  E5%  8C%  97%  E4%  BA%  AC%  E5%  A4%  A7%  E5%  AD%  A6
mc = %25E5%258C%2597%25E4%25BA%25AC%25E5%25A4%25A7%25E5%25AD%25A6
这个网页的二次编码只是骗骗外行人的,二次编码是在一次编码的基础上把"%"替换为"%25"即可,不需要进行二次编码

问题是:现在刚好是25,以后会不会变,有人还把他说是加密编码,也不知encodeURI的标准会不会变,实际应用编码时还是用encodeURI来处理稳妥点,故在此略提一下encodeURI。
#18
jinanshui2021-05-29 16:24
谢谢两位老师
#19
hugeston2022-01-07 14:27
回复 2楼 sdta
https://xkkm.
2024年的数据如何提取?跪谢!!969651281@
#20
jinanshui2022-01-07 19:20
回复 19楼 hugeston
同求,我鼓捣了半年,也没弄出来,还是用了sdta老师的数据,2024年还要考各位大侠。最好大侠把代码发出来,谢谢

[此贴子已经被作者于2022-1-7 19:21编辑过]

#21
吹水佬2022-01-07 20:41
好象下载 xx.html 就可以
只有本站会员才能查看附件,请 登录

程序代码:
url =  "https://xkkm./web/xx.html"
wh = CREATEOBJECT("WinHttp.WinHttpRequest.5.1")
wh.Open("GET", url, 0)
wh.Send()
trs = STREXTRACT(wh.ResponseText,[<tbody],[</tbody])
CREATE CURSOR tt (序号 I,地区 C(10),学校代码 C(6),学校名称 C(20),选考科目要求 C(10),学校网址 C(100))
n = AT("<tr>",trs)
DO WHILE n>0
    trs = SUBSTR(trs,n+4)
    INSERT INTO tt VALUES (;
        VAL(STREXTRACT(trs,[>],[<],1)),;
        STREXTRACT(trs,[>],[<],3),;
        STREXTRACT(trs,[>],[<],5),;
        STREXTRACT(trs,[>],[<],7),;
        STREXTRACT(trs,[>],[<],10),;
        STREXTRACT(trs,[>],[<],19))
    n = AT("<tr>",trs)
ENDDO
SELECT * FROM tt
#22
jinanshui2022-01-08 02:47
回复 21楼 吹水佬
只有本站会员才能查看附件,请 登录
#23
吹水佬2022-01-08 12:37
回复 22楼 jinanshui
是不是网路问题
试试将
wh = CREATEOBJECT("WinHttp.WinHttpRequest.5.1")
改为
wh = CREATEOBJECT("MSXML2.XMLHTTP")
#24
jinanshui2022-01-08 15:05
回复 23楼 吹水佬
谢谢,老师,可以采集到这一页的信息,我们的想法是把各个学校的信息采集出来,麻烦老师再考虑一下.
#25
jinanshui2022-01-08 15:08
回复 23楼 吹水佬
老师,例如
只有本站会员才能查看附件,请 登录

#26
吹水佬2022-01-08 22:20
回复 25楼 jinanshui
只有本站会员才能查看附件,请 登录

程序代码:

cPath = ADDBS(JUSTPATH(SYS(16)))
SET DEFAULT TO (cPath)

DECLARE LONG _strdup IN msvcrt as apiStrdup STRING@
DECLARE LONG free    IN msvcrt as apiFree   LONG
DECLARE LONG strstr  IN msvcrt as apiStrstr LONG,STRING@

CREATE CURSOR tt (序号 I,地区 C(10),学校代码 C(6),学校名称 C(30),选考科目要求 C(10),学校网址 C(100))
CREATE CURSOR tmp (序号 I,层次 C(10),专业类名称 C(50),选考科目范围 C(100),类中所含专业 C(240))

jsCode = [function encode(unencoded){return encodeURIComponent(unencoded).replace(/'/g,"%27").replace(/"/g,"%22");}]
sc = CREATEOBJECT("ScriptControl")
sc.Language = "JavaScript"
sc.AddCode(jsCode)

wh = CREATEOBJECT("WinHttp.WinHttpRequest.5.1")
wh.Open("GET", "https://xkkm./web/xx.html", 0)
wh.Send()
trs = STREXTRACT(wh.ResponseText,[<tbody],[</tbody])

ps = apiStrdup(trs)
p1 = apiStrstr(ps,"<tr>")
DO WHILE p1>0
    p2 = apiStrstr(p1,"</tr>")
    tds = SYS(2600, p1+4, p2-p1-4)
    INSERT INTO tt VALUES (;
        VAL(STREXTRACT(tds,[>],[<],1)),;
        STREXTRACT(tds,[>],[<],3),;
        STREXTRACT(tds,[>],[<],5),;
        STREXTRACT(tds,[>],[<],7),;
        STREXTRACT(tds,[>],[<],10),;
        STREXTRACT(tds,[>],[<],19))
    p1 = apiStrstr(p2,"<tr>")
ENDDO
apiFree(ps)

** 示例只取一个学校,DBF文件名格式:学校名称(学校代码).DBF
SELECT tt
LOCATE FOR ALLTRIM(学校代码)=="10007"
ckxq(ALLTRIM(学校代码),ALLTRIM(学校名称))

CLOSE DATABASES ALL
CLEAR ALL
RETURN

FUNCTION ckxq(cDM,cMC)
    cDBF = cMC+"("+cDM+")"
    SELECT tmp
    COPY TO (cDBF)
    USE (cDBF) IN 0 ALIAS mc
    wh.Open("POST", "https://xkkm./xkkm/queryXxInfor", 0)
    wh.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
    wh.Send("dm="+cDM+"&mc="+encodeURI(encodeURI(cMC))+"&yzm=ok")
    trs = STREXTRACT(wh.ResponseText,[<tbody],[</tbody])
    ps = apiStrdup(trs)
    p1 = apiStrstr(ps,"<tr ")
    DO WHILE p1>0
        p1 = apiStrstr(p1,"<td ")
        p2 = apiStrstr(p1,"</tr>")
        tds = SYS(2600, p1, p2-p1)
        INSERT INTO mc VALUES (;
            VAL(STREXTRACT(tds,[>],[<],1)),;
            STREXTRACT(tds,[>],[<],3),;
            ALLTRIM(STREXTRACT(tds,[>],[<],5),0h0D,0h0A,0h20),;
            STREXTRACT(tds,[>],[<],7),;
            STRTRAN(ALLTRIM(STREXTRACT(tds,[>],[</td>],11),0h0D,0h0A,0h20),"<br/>",","))
        p1 = apiStrstr(p2,"<tr ")
    ENDDO
    apiFree(ps)
    USE IN "mc"
ENDFUNC

FUNCTION encodeURI(cUnencoded)
    RETURN sc.run("encode", cUnencoded)
ENDFUNC
#27
jinanshui2022-01-10 00:21
回复 26楼 吹水佬
谢谢吹版,可以了,谢谢
#28
jinanshui2022-01-10 08:50
回复 26楼 吹水佬
谢谢吹版主老师,我现在试着怎样把全部学校都下载到一个dbf中
#29
吹水佬2022-01-10 11:37
以下是引用jinanshui在2022-1-10 08:50:29的发言:

谢谢吹版主老师,我现在试着怎样把全部学校都下载到一个dbf中

一个学校一个表不好吗
如果学校之间的数据没什么关联就无必要合并在一起,这样处理数据相对便捷高效些
需要学校之间某些数据整合时再筛选处理
#30
jinanshui2022-01-11 12:08
回复 29楼 吹水佬
谢谢,吹版主老师,您说得太对了.
#31
jinanshui2022-01-17 10:23
回复 29楼 吹水佬
吹水佬版主老师,又不行了,难倒有事网络的事?又给您添麻烦.
只有本站会员才能查看附件,请 登录
#32
吹水佬2022-01-17 11:16
回复 31楼 jinanshui
请求异常,原因不明,网路、服务器端.....都有可能
加个异常处理过程,出现异常时另作处理
1