核心原理

网页登录的本质是:你的浏览器向服务器提交一个包含用户名和密码的表单,服务器验证这些信息,如果正确,就创建一个会话(Session)并返回一个凭证(通常是Cookie),之后你访问该论坛的其他页面时,浏览器都会带上这个Cookie,证明你已经登录。

在易语言中,我们模拟这个过程:

  1. 构造登录请求:准备好登录页面的地址、需要提交的用户名和密码。
  2. 发送POST请求:使用易语言的.NET支持库中的HttpWebRequest组件,向服务器发送一个POST请求,并将用户名和密码作为数据一同发送。
  3. 接收响应:服务器会返回一个响应,如果登录成功,这个响应通常会包含一个或多个Set-Cookie头,这就是登录凭证。
  4. 保存凭证:将这些Cookie保存下来。
  5. 后续操作:在之后访问论坛任何需要登录的页面时,都带上这些Cookie,服务器就会认为你已经登录。

准备工作

  1. 安装易语言:确保你的电脑上安装了易语言。
  2. 打开易语言:新建一个“Windows窗口程序”。
  3. 添加.NET支持库
    • 点击“窗口”菜单 -> “支持库...”。
    • 在弹出的对话框中,勾选“.NET”框架支持库。
    • 点击“增加”,找到易语言安装目录下的易语言.NET支持库.ec文件,然后点击“确定”。

第一步:分析目标登录页面

在写代码之前,我们必须先分析你要登录的论坛登录页面,以一个典型的论坛为例(这里我们以一个虚构的论坛 http://www.example.com/bbs/login.php 为例进行说明):

  1. 打开浏览器(如Chrome、Edge),访问论坛的登录页面。
  2. 按F12 打开开发者工具,切换到“网络”选项卡。
  3. 刷新页面,确保网络列表是干净的。
  4. 在登录表单中输入任意用户名和密码,然后点击“登录”按钮。
  5. 在网络列表中,找到你刚刚点击登录后产生的那一条请求,它的“方法”通常是 POST,地址就是登录处理的URL。
  6. 点击这条请求,查看它的“标头”和“载荷”(或“表单数据”)。

你需要关注的关键信息:

  • 请求 URL: http://www.example.com/bbs/login.php
  • 请求方法: POST
  • 表单数据: 这是最重要的!它显示了浏览器提交了哪些数据,通常包括:
    • username: 你的用户名
    • password: 你的密码
    • formhash: 很多论坛为了防止CSRF攻击,会有一个动态的哈希值,这个值必须在登录时提交。
    • remember: "记住我" 选项的值。
    • submit: "登录" 按钮的值。

假设我们分析得到以下信息:

  • 登录URL: http://www.example.com/bbs/login.php
  • 提交的数据: username=你的用户名&password=你的密码&formhash=12345678&submit=登录

第二步:设计易语言窗口

在易语言窗口上拖拽以下控件:

  • 一个“编辑框”,变量名为 用户名编辑框,用于输入用户名。
  • 一个“编辑框”,变量名为 密码编辑框,将其“密码”属性设为 ,用于输入密码。
  • 一个“按钮”,变量名为 登录按钮为“登录”,点击事件将触发登录逻辑。
  • 一个“超级列表框”,变量名为 日志列表框,用于显示登录过程中的信息,方便调试。
  • 一个“标签”,标题为“Cookie:”,用于显示登录成功后获取到的Cookie。
  • 一个“编辑框”,变量名为 Cookie编辑框,只读,用于显示Cookie。

第三步:编写核心代码

双击“登录按钮”,进入其“_被单击”事件,编写如下代码:

.版本 2
.程序集 窗口程序集_启动窗口
.子程序 _登录按钮_被单击
.局部变量 post数据, 文本型
.局部变量 http请求, HttpWebRequest
.局部变量 http响应, HttpWebResponse
.局部变量 响应流, Stream
.局部变量 读取器, StreamReader
.局部变量 返回内容, 文本型
.局部变量 cookie容器, CookieContainer
' --- 1. 准备要提交的数据 ---
' 注意:这里的用户名、密码、formhash等字段名,必须和你分析网页时得到的一致!
post数据 = “username=” + 用户名编辑框.内容 + “&password=” + 密码编辑框.内容 + “&formhash=12345678&submit=登录”
' --- 2. 创建和配置HTTP请求 ---
' 创建Cookie容器,用于保存服务器返回的Cookie
cookie容器 = 创建 CookieContainer()
' 创建HttpWebRequest对象
http请求 = 创建 HttpWebRequest
http请求.地址 = “http://www.example.com/bbs/login.php” ' 替换为你的真实登录URL
http请求.方法 = “POST” ' 设置请求方法为POST
http请求.内容类型 = “application/x-www-form-urlencoded” ' 告诉服务器我们提交的是表单数据
http请求.允许自动重定向 = 真 ' 如果登录后跳转,允许跟随
http请求.CookieContainer = cookie容器 ' 将Cookie容器附加到请求上
' --- 3. 发送POST数据 ---
' 将字符串数据转换为字节流
.如果真 (post数据 ≠ “”)
    .局部变量 数据字节, 字节集
    数据字节 = 到字节集 (post数据, #编码_UTF8)
    ' 获取请求流并写入数据
    http请求.内容长度 = 取字节集长度 (数据字节)
    .局部变量 请求流, Stream
    请求流 = http请求.获取请求流 ()
    请求流.写入 (数据字节, 0, 取字节集长度 (数据字节))
    请求流.关闭 ()
.如果真结束
' --- 4. 获取服务器响应 ---
.计次循环首 (1, 1) ' 加入循环是为了处理可能的异常
    .异常捕捉
        http响应 = http请求.获取响应 ()
    .异常尾
        .(错误信息 ≠ 空)
            日志列表框.加入项目 (“登录失败!错误信息:” + 错误信息, , , 假)
            返回 ()
        .否则
            跳出循环 ()
        .如果结束
    .异常结束
.计次循环尾 ()
' --- 5. 读取响应内容 ---
' 这部分可以用来判断登录是否成功,比如服务器会返回“登录成功”或“用户名/密码错误”等字样
响应流 = http响应.获取响应流 ()
读取器 = 创建 StreamReader, 响应流, #编码_UTF8= 读取器.读取至末尾 ()
显示在日志里,方便调试
日志列表框.加入项目 (“服务器返回内容:”, , , 假)
日志列表框.加入项目 (返回内容, , , 假)
' --- 6. 保存并显示Cookie ---
' 从Cookie容器中获取所有Cookie
.局部变量 cookies, Cookie()
cookies = cookie容器.获取Cookies (http请求.地址)
.(取数组成员数 (cookies) > 0)
    .局部变量 cookie字符串, 文本型
    cookie字符串 = “”
    .计次循环首 (取数组成员数 (cookies), i)
        cookie字符串 = cookie字符串 + cookies [i].名称 = “” + cookies [i].值 + “; ”
    .计次循环尾
    ' 去掉最后的分号和空格
    cookie字符串 = 取文本左边 (cookie字符串, 取文本长度 (cookie字符串) - 2)
    ' 将Cookie显示在编辑框中
    Cookie编辑框.内容 = cookie字符串
    日志列表框.加入项目 (“登录成功!已获取Cookie:”, , , 假)
    日志列表框.加入项目 (cookie字符串, , , 假)
.否则
    日志列表框.加入项目 (“登录失败!未获取到任何Cookie。”, , , 假)
.如果结束
' --- 7. 关闭流和对象 ---
读取器.关闭 ()
响应流.关闭 ()
http响应.关闭 ()
http请求.关闭 ()
' --- 8. 后续操作示例 ---
' 假设我们要访问一个需要登录才能查看的帖子页面
.(Cookie编辑框.内容 ≠ “”)
    .局部变量 访问请求, HttpWebRequest
    .局部变量 访问响应, HttpWebResponse
    .局部变量 访问内容, 文本型
    访问请求 = 创建 HttpWebRequest
    访问请求.地址 = “http://www.example.com/bbs/thread-12345-1-1.html” ' 替换为需要登录的页面URL
    访问请求.方法 = “GET”
    ' 关键!再次使用同一个CookieContainer,这样请求就会带上之前保存的登录凭证
    访问请求.CookieContainer = cookie容器
    .异常捕捉
        访问响应 = 访问请求.获取响应 ()
        .局部变量 访问流, Stream
        访问流 = 访问响应.获取响应流 ()
        .局部变量 访问读取器, StreamReader
        访问读取器 = 创建 StreamReader, 访问流, #编码_UTF8
        访问内容 = 访问读取器.读取至末尾 ()
        日志列表框.加入项目 (“--- 尝试访问登录后页面 ---”, , , 假)
        ' 通常只截取一部分内容显示,防止日志框爆掉
        日志列表框.加入项目 (取文本左边 (访问内容, 200), , , 假)
        访问读取器.关闭 ()
        访问流.关闭 ()
        访问响应.关闭 ()
    .异常尾
    访问请求.关闭 ()
.如果结束

关键点解析

  1. CookieContainer:这是整个登录流程的灵魂,它像一个“Cookie罐子”,你把服务器给你的Cookie放进去,之后再用这个罐子去发请求,它会自动把里面的Cookie都带上,无论是登录请求还是后续的请求,都要使用同一个CookieContainer实例。

  2. Content-Type:设置为 application/x-www-form-urlencoded 是标准的做法,告诉服务器我们发送的是HTML表单格式的数据,如果网站使用的是JSON格式,就需要设置为 application/json

  3. Content-Length:在发送POST数据前,设置好请求体的长度,这是一个好习惯。

  4. 异常处理:网络请求非常不稳定,可能会因为网络问题、服务器错误等而失败,使用.异常捕捉可以防止程序意外崩溃,并给出友好的错误提示。

  5. 调试日志列表框是最好的朋友,把请求的URL、发送的数据、返回的内容、获取的Cookie都打印出来,一旦出错,你就能快速定位问题所在,如果返回内容里有“密码错误”,那说明你的密码或用户名错了;如果返回内容是登录页面的HTML,那说明登录失败,页面被重定向回了登录页。


常见问题与解决方法

  1. 问题:登录后,访问其他页面还是提示未登录。

    • 原因:最可能的原因是CookieContainer没有正确传递,请确保登录请求和后续请求使用的是同一个CookieContainer对象。
    • 原因:有些论坛的登录页面和实际处理登录的URL是分开的,或者登录后会跳转,请确保你POST的URL是正确的(通过F12开发者工具确认)。
    • 原因:网站有动态的formhash,每次登录页面的formhash都不同,你需要先GET登录页面,用正则表达式或文本处理函数从页面源码中提取出formhash,然后再进行POST。
  2. 问题:服务器返回“405 Method Not Allowed”错误。

    • 原因:你请求的URL不支持POST方法,或者URL错误,请再次用F12确认登录请求的准确URL。
  3. 问题:返回的内容是乱码。

    • 原因:网站的编码可能不是UTF-8,你需要查看登录页面的<head>部分,找到<meta charset="...">标签,确认其编码(可能是GBKGB2312),然后将代码中的#编码_UTF8改为对应的编码,例如#编码_GBK
  4. 问题:需要验证码。

    • 原因:这是反爬虫机制,处理方法通常更复杂:
      • 图片验证码:需要先GET登录页面,下载验证码图片,然后让用户手动输入,或者调用OCR接口识别。
      • 短信验证码:需要用户自己接收并输入。

希望这个详细的教程能帮助你成功实现易语言的论坛登录功能!祝你编程愉快!