一. 爬虫的爬行方式
1. 从哪里开始: 根集
挑选根集时, 应该从足够多不同的站点中选择URL, 这样,爬遍所有的链接才能最终到达大部分你感兴趣的Web页面。
2. 链接的提取以及相对链接的标准化
3 . 避免环路的出现
机器人必须知道它们到过何处, 以避免环路的出现。环路会造成机器人陷阱, 这些陷阱会暂停或减缓机器人的爬行进程。
4 . 循环与复制
至少出千下列三个原因, 环路对爬虫来说是有害的。
5 . 面包屑留下的痕迹
记录曾经到过哪些地方井不总是一件容易的事,这里列出了大规模Web爬虫对其访问过的地址进行管理时使用的一些有用的技术。
6. 别名与机器人环路
由于URL “别名” 的存在, 即使使用了正确的数据结构, 有时也很难分辨出以前是否访问过某个页面。如果两个URL 看起来不一样, 但实际指向的是同一资源, 就称这两个URL 互为“别名” 。
9-1 同一文档的不同URL别名
| 第一个URL | 第二个URL | 什么时候是别名 | |
|---|---|---|---|
| a | http://www.foo.com/bar.html | http://www.foo.com:80/bar.html | 默认端口为80 |
| b | http://www.foo.com/~fred | http://www.foo.com/%7Ffred | %7F与~相同 |
| c | http://www.foo.com/x.html#arly | http://www.foo.com/x.html#middle | 标签井没有修改页面内容 |
| d | http://www.foo.com/readme.htm | http://www.foo.com/README.HTM | 服务器是大小写无关的 |
| e | http://www.foo.com/ | http://www.foo.com/index.html | 默认页面为index.html |
| f | http://www.foo.com/index.html | http://209.231.87.45/indcx.html | www.foo.com使用这个IP地址 |
7. 规范化URL
经过这些步骤就可以消除表9-1中a-c所列的别名问题了。
8. 文件系统连接环路
件系统中的符号连接会造成特定的潜在环路, 因为它们会在目录层次深度有限的情况下,造成深度无限的假象。
图9-3b的文件系统中, 可能会发生下列情况:
图9-3b的问题是subdir/是个指向”!” 的环路, 但由千URL 看起来有所不同, 所以机器人无法单从URL本身判断出文档是相同的。毫无戒备的机器人就有了陷入循环的危险。
9. 动态虚拟Web空间
恶意网管可能会有意创建一些复杂的爬虫循环来陷害那些无辜的、亳无戒备的机器人。尤其是, 发布一个看起来像普通文件, 实际上却是网关应用程序的URL 是很容易的。这个应用程序可以在传输中构造出包含了到同一服务器上虚构URL 链接的HTML。请求这些虚构的URL时, 这个邪恶的服务器就会捏造出一个带有新的虚构URL的新HTML页面来。
即使这个恶意Web服务器实际上井不包含任何文件, 它也可以通过无限虚拟的Web空间将可怜的机器人带人爱丽丝漫游仙境之旅。更糟的是, 每次的URL和HTML看起来都有很大的不同, 机器人很难检测到环路。图9-4显示了一个恶意Web服务器生成假内容的例子。
10. 避免循环和重复
在机器人会遇到的各种危险的Web中, 有些技术的使用可以使机器人有更好的表现。
要小心, 这种技术肯定会让你错过一些内容。现在很多站点都会用URL来管理用户的状态(比如, 在一个页面引用的URL中存储用户ID)。用URL长度来限制爬虫可能会带来些麻烦`但如果每当请求的URL达到某个特定长度时, 都记录一次错误的话, 就可以为用户提供一种检查某特定站点上所发生情况的方法。
这就要求有人工进行干预。但现在很多大型爬虫产品都有某种形式的黑名单, 用于避开某些存在固有问题或者有恶意的站点。还可以用黑名单来避开那些对爬行大惊小怪的站点。
必须对校验和函数进行选择, 以求两个不同页面拥有相同校验和的几率非常低。MDS这样的报文摘要函数就常被用千指纹计算。
有些Web服务器会在传输过程中对页面进行动态的修改, 所以有时机器人会在校验和的计贷中忽略Web页面内容中的某些部分, 比如那些嵌入的链接。而且,无论定制了什么页面内容的动态服务器端包含(比如添加日期、访问计数等)都可能会阻碍重复检测。
二. 机器人的HTTP
机器人和所有其他HTTP客户端程序井没有什么区别。它们也要遵守HTTP规范中的规则。发出HTTP请求并将自己广播成HTTP/1.1客户端的机器人也要使用正确的HTTP请求首部。
很多机器人都试图只实现请求它们所查找内容所需的最小HTIP集。这会引发一些问题,但短期内这种行为不会发生什么改变。结果就是, 很多机器人发出的都是HTTP/1.0请求, 因为这个协议的要求很少。
1. 识别请求首部
尽管机器人倾向于只支持最小的HTIP集, 但大部分机器人确实实现井发送了一些识别首部一一最值得一提的就是User-Agent 首部。建议机器人实现者们发送一些基本的首部信息, 以通知各站点机器人的能力、机器人的标识符, 以及它是从何处起源的。
在追踪错误爬虫的所有者, 以及向服务器提供机器人所能处理的内容类型时, 这些信息都是很有用的。鼓励机器人实现者们使用的基本识别首部包括如下内容。
2. 虚拟主机
机器人实现者要支持Host 首部。随着虚拟主机(参见第5章)的浣行, 请求中不包含Host首部的话, 可能会使机器人将错误的内容与一个特定的URL关联起来。因此, HTTP/1.1要求使用Host首部。
在默认情况下, 大多数服务器都被配置为提供一个特定的站点。因此, 不包含Host首部的爬虫向提供两个站点的服务器发起请求时, 就像图9-5中的站点一样(www.joes-hardware.com和www.foo.com), 假设默认情况下服务器被配置为提供WWW.joes-hardware.com站点(且不需要Host首部), 那么, 若请求www.foo.com上的某个页面, 爬虫实际获取的就是Joe的五金商店的站点上的内容。更糟糕的是, 爬虫会认为来自Joe的五金站点上的那些内容是来自www.foo.com的。如果带有相对立的政治色彩或其他观点的两个站点是由同一台服务器提供的, 你肯定能想象到会有更不幸的局面出现。
3. 条件请求
鉴于这些机器人的努力程度, 尽量减少机器人所要获取内容的数量通常是很有意义的。对因特网搜索引擎机器人来说, 需要下载的潜在页面有数十亿, 所以, 只在内容发生变化时才重新获取内容是很有意义的。
有些机器人实现了条件HTTP请求, “它们会对时间戳或实体标签进行比较, 看看它们最近获取的版本是否已经升级了。这与HTTP缓存查看已获取资源的本地副本是否有效的方法非常相似。更多与缓存对资源本地副本的验证有关的信息请参见第7章。
4. 对响应的处理
很多机器人的兴趣主要在千用简单的GET方法来获取所请求的内容,所以,一般不会在处理响应的方式上花费太多时间。但是,使用了某些HTTP特性(比如条件请求)的机器人,以及那些想要更好地探索服务器,井与服务器进行交互的机器人则要能够对各种不同类型的HTTP响应进行处理。
1 . 状态码
总之,机器人至少应该能够处理一些常见的,以及预期的状态码。所有机器人都应该理解200 OK和404 Not Found这样的状态码。它们还应该能够根据响应的一般类别对它并不十分理解的状态码进行处理。第3章的表3-2给出了不同状态码的分类及其含义。
有些服务器并不总能返回适当的错误代码,认识到这一点是很重要的。有些服务器甚至会将HTTP状态码200 OK与描述错误状态的报文主体文本一同返回!很难对此做些什么一只是实现者应该要了解这些情况。
2 . 实体
除了HTTP首部所嵌的信息之外,机器人也会在实体中查找信息。HTML元标签,比如元标签http-equiv, 就是内容编写者用千嵌入资源附加信息的一种方式。
胀务器可能会为它所处理的内容提供一些首部,标签http-equiv为内容编写者提供了一种覆盖这些首部的方式:
这个标签会指示接收者处理这个文档时,要当作其HTTP响应首部中有一个值为l,URL=index.h七ml’的RefreshHTTP首部。
5. User-Agent导向
三. 行为不当的机器人
四. 拒绝机器人访问
1. 拒绝机器人访问标准
表9-2 拒绝机器人访问标准的版本
| 版本 | 标题及描述 | 日期 |
|---|---|---|
| 0.0 | 拒绝机器人标准-Martijo Koster提出的带右Disallow (不允许)指令的原始robots.txt机制 | 1994年6月 |
| 1.0 | 控制Web机器人的方法一Martijn Koster提供了额外支持Allow (允许)的IETF草案 | 1996年11月 |
| 2.0 | 拒绝机器人访问的扩展标准一Sean Conner提出的扩展标准, 包括了正则表达式和定时信息,没有得到广泛的支持 | 1996年11月 |
2. Web站点和robots.txt文件
1 . 获取robots.txt
机器人会用HTTP的GET 方法来获取robots.txt资源, 就像获取Web 服务器上所有
其他资源一样。如果有robots.txt文件的话, 服务器会将其放在一个textlplain主体
中返回。如果服务器以404 Not Found HTTP 状态码进行响应, 机器人就可以认为这
个服务器上没有机器人访问限制, 它可以请求任意的文件。
机器人应该在From首部和User心gent首部中传输标识信息, 以帮助站点管理者
对机器人的访问进行跟踪, 井在站点管理者要查询, 或投诉的机器人事件中提供一
些联系信息。下面是一个来自商业Web机器人的HTTP 爬虫请求实例:
2 . 响应码
很多Web站点都没有robots.txt资源, 但机器人井不知道这一点。它必须尝试着从
每个站点上获取robots.txt资源。机器人会根据对robots.txt检索的结果采取不同的
行动。
• 如果服务器以—个成功状态(HTIP状态码2XX)为响应, 机器人就必须对内容
进行解析, 并使用排斥规则从那个站点上获取内容。
• 如果服务器响应说明资源并不存在(HTTP状态码404),机器人就可以认为服务
器没有激活任何排斥规则, 对此站点的访问不受robots.txt的限制。臣且
• 如果服务器响应说明有访问限制(HTTP状态码401或403),机器人就应该认为
对此站点的访问是完全受限的。
• 如果请求尝试的结果是临时故障(HITP状态码503),机器人就应该推迟对此站
点的访问, 直到可以获取该资源为止。
• 如果服务器响应说明是重定向(HTTP状态码3XX),机器人就应该跟着重定向,
直到找到资源为止。
3. robots.txt文件的格式
# this robots.txt file allows Slurp & Webcrawler to crawl # the public parts of our site, but no other robots ... User-Agent: slurp User-Agent: webcrawler Disallow: /private User-Agent: • Disallow:
1. User-Agent行
每个机器人记录都以一个或多个下列形式的User-Agent行开始:
User-Agent:
或
User-Agent: *
• 第一个
是机器人名的大小写无关的子字符串,
• 第一个
为”*”。
2. Disallow和Allow行
Disallow和Allow行紧跟在机器人排斥记录的User-Agent行之后。用来说明显
式禁止或显式允许特定机器人使用哪些URL路径。
机器人必须将期望访问的URL按序与排斥记录中所有的Disallow和Allow规
则进行匹配。使用找到的第一个匹配项。如果没有找到匹配项, 就说明允许使用这
个URL。
http://www.joes-hardware.com/tmp
http://www.joes-hardware.com/tmp/
http://www.joes-hardware.com/tmp/pliers.html
http://www.joes-hardware.com/tmpspc/stuff.txt
3. Disallow/Allow前缀匹配
下面是Disallow/Allow 前缀匹配的一些细节。
• Disallow 和Allow 规则要求大小写相关的前缀匹配。(与User-Agent 行不同)这里的星号没什么特殊的含义, 但空字符串可以起到通配符的效果。
• 在进行比较之前, 要将规则路径或URL路径中所有”被转义” 的字符(%XX)都反转为字节(除了正斜杠%2F之外, 它必须严格匹配)。
• 如果规则路径为空字符串, 就与所有内容都匹配。
表9-3 列出了几个在规则路径和URL 路径间进行匹配的例子。
表9-3 robots.txt路径匹配示例
| 规则路径 | URL路径 | 匹配吗? | 注释 |
|---|---|---|---|
| /tmp | /tmp | ✓ | 规则路径==URL路径 |
| /tmp | /tmpfile.html | ✓ | 规则路径是URL路径的前缀 |
| /tmp | /tmp/a.htrnl | ✓ | 规则路径是URL路径的前缀 |
| /tmp/ | /tmp | ✕ | /tmp/不是/tmp的前缀 |
| README.TXT | ✓ | 空的规则路径匹配千所有的路径 | |
| /-fred/hi.html | /% 7Efred/hi.html | ✓ | 将%7E与~同等对待 |
| /% 7Efred/hi.html | /-fred小i.html | ✓ | 将%7E与~同等对待 |
| /%7efred/hi.html | /%7Efred小i.html | ✓ | 转义符是大小写无关的 |
| /~fred/hi.html | -fred%2Fhi.html | ✕ | %2F是一个斜杠, 但斜杠是种特殊情况, 必须完全匹配 |
4. 其他有关robots.txt的知识
解析robots.txt文件时还甜遵循其他一些规则。
• 为了实现后向兼容,不能在中间断行。
5. 缓存和robots.txt的过期
6. 拒绝机器人访问的Perl代码
• 创建RobotRules 对象
$rules = WWW::RobotRules->new($robot_name);
• 装载robots.txt 文件
$rules->parse($url, $content, $fresh_until);
• 查看站点URL是否可获取
$can_fetch = $rulee-:;,allowed($url);
下面这个短小的Perl 程序说明了WWW: :RobotRules 的用法:
require WWW:: RobotRules; # Create the RobotRules object, naming the robot "SuperRobot" my $robotsrules = new WWW: : Robo仁Rules 'SuperRobot/1.0'; use LWP::Simple qw(get); # Get and parse the robots.txt file for Joe's Hardware, accumulating # the rules $url = "http://www.joes-hardware.com/robots.txt"; my $robots_txt = get $url; $robotsrules->parse($url, $robots_txt); # Get and parse the robots.txt file for Mary's Antiques, accumulating # the rules $url = "http://www.mary's antiques.com/robots.txt"; my $robots_txt ; get $url; $robotsrules->parse($url, $robots_txt); # Now RobotRules contains the set of robot exclusion rules for several # different sites. It keeps them all separate. Now we can use RobotRules # to test if a robot is allowed to access various URLs. if ($robotsrules->allowed($some target url)) { $c = get $url; ... }
下面是www.marys-antiques.com 的假想robots.txt 文件:
# This is the robots.txt file for Mary's Antiques web site # Keep Suzy's robot out of all the dynamic URLs because it doesn't # understand them, and out of all the private data, except for 匕he # small section Mary has reserved on the site for Suzy. User-Agent: Suzy-Spider Disallow: /dynamic Allow: /private/suzy-stuff Disallow: /private. # The Furniture-Finder robot was specially designed to understand # Mary's antique store's furniture inventory program, so let it # crawl that resource, but keep it out of all the other dynamic # resources and out of all the private data. Oser-Agent: Furniture-Finder Allow: /dynamic/check-inventory Disallow: /dynamic Disallow: /private # Keep everyone else out of the dynamic gateways and private data. User-Agent: * Disallow: /dynamic Disallow: /private
• SuzySpider 的排斥记录不允许机器人爬行以/dynamic 开头的商店库存网关URL,以及在为Suzy 保留的区域之外的其他私有用户数据。
• FumitureFinder 机器人的记录允许机器人爬行家具库存网关URL。这个机器人可能能够理解Mary 的网关格式和规则。
• 其他机器人都不能访问所有的动态和私有Web 页面, 但它们可以爬行其余的URL。
| URL | SuzySpider | FumitureFlnder | NosyBot |
|---|---|---|---|
| http://www.marys-antiques.com/ | ✓ | ✓ | ✓ |
| http:/lwww.marys-antiques.com/index.html | ✓ | ✓ | ✓ |
| http://www.marys-antiques.com/private/payroll.xls | X | X | X |
| http://www.marys-antiques.com/private/suzy-stuff/taxes.txt | ✓ | X | X |
| http://www.marys-antiques.com/dynamic/buy-stuff?id=3546 | X | X | X |
| http://www.marys-antiques.com/dynamic/chcck-inventory?kitchen | X | ✓ | X |
7. HTML的robot-control元标签
机器人排斥标签是以如下形式, 通过HTML 的META 标签来实现的:
1. 机器人的META指令
机器人META 指令有几种不同的类型, 而且随着时间的推移, 以及搜索引擎及机器
人对其行为和特性集的扩展, 很可能还会添加一些新的指令。最常用的两个机器人
META 指令如下所示。
... ...
| name= | content= | 描述 |
|---|---|---|
| DESCRIPTION |
<文本>< td=""> 文本><> |
允许作者为Web页面定义一个短小的文本摘要. 很多搜索引擎都会查看META DESCRIPTION标签, 允许页面作者指定一些短小的摘要来描述其Web页面 |
| KEYWORDS | <逗号列表> | 关联一个由逗号分隔的Web页面描述词列表, 为关键字搜索提供帮助 |
| REVISIT-AFTER |
<天数>< td=""> 天数><> |
告诉机器入或搜索引擎应该在指定天数之后重访页面,估计那时候页面可能会发生变化 |
5. 机器人的规范
表9-6 Web机器人操作员指南
| 操作指南 | 描述 |
|---|---|
| (1)识别 | |
| 识别你的机器入 | 用HITP的User-Agent字段将机器人的名字告诉Web服务器。这样可以帮助管理员理解机器人所做的事情。有些机器人还会在User-Agent首部包含一个描述机器入目的和策略的URL |
| 识别你的机器 | 确保机器人是从一台带有DNS条目的机器上运行的,这样Web站点才能够将机器人的IP地址反向DNS为主机名。这有助于管理者识别出对机器人负资的组织 |
| 识别联络人 | 用HTTP的From字段提供一个联络的E-mail地址 |
| (2)操作 | |
| 保持警惕 | 机器人可能会惹一些麻烦或引发一些抱怨. 其中一些是由那些行为有偏差的机器人造成的. 一定要小心, 注意保持机器人的正常行为. 如果机器人要全天候运行, 就要格外小心。需要有操作人员不间断地对机器人进行监视, 直到它有了丰富的经验为止 |
| 做好准备 | 开始一次重要的机菩人之旅时, 一定要通知你所在的组织. 你的组织可能要观测网络带宽的耗费, 作好应对各种公共查询的准备 |
| 监视并记录日志 | 机器入应该装备有丰富的诊断和日志记录工具, 这样才能记录进展、识别所有的机器人陷阱` 进行完整性桧壹看看工作是否正常。监视井记录机器人行为的重要性怎么强调也不过分. 问题和抱怨总是会有的, 对爬虫行为的详细记录, 有助千机器人操作者回溯所发生的事情. 不管是为了调试出错的Web爬虫, 还是为了在不合理的投诉面前为其行为进行辩护, 监视和记录工作都是非常重要的 |
| 学习并适应 | 在每次爬行中你都会学到新的东西. 要让机器人逐步适应, 这样, 它在每次爬行之后都会有所进步, 并能避开一些常见的陷阱 |
| (3)约束自己的行为 | |
| 对URL进行过滤 | 如果一个URL指向的好像是你不理解或不感兴趣的数据, 你可能会希望跳过它。比如, 以.z、.gz 、.tar或者.zip结尾的URL很可能是压缩文件或归档文件。以.exe结尾的URL可能就是程序. 以.gif、tif、.jpg结尾的URL很可能是图片。要确保你得到的就是你想要的 |
| 过滤动态URL | 通常, 机器人不会想去爬行来自动态网关的内容. 机器人不知道应该如何正确地格式化查询请求, 井将其发送给网关, 而它得到的结果也很可能是错误的或临时的. 如果一个URL中包含了cgi, 或者有一个“?飞机器人可能就不会去爬行这个URL了 |
| 对Accept首部进行过滤 | 机器人应该用HTTP的Accept首部来告诉服务器它能够理解哪种内容 |
| 遵循robots.txt | 机器人应该接受站点上robots.txt的控制 |
| 制约自己 | 机器人应该记录访间每个站点的次数以及访间的时间, 井通过这些信息来确保它没有太频繁地访问某个站点.机器入访问站点的频率高于儿分钟一次时, 管理员就要起疑心了.机器人每隔几秒钟就访问一次站点时, 有些管理员就会生气了。机器人尽可能频繁地去访间一个站点, 将所有其他浣量都拒之门外时, 管理员就会暴怒起来。 |
| 总之, 应该限制机器人, 使其每分钟最多只发送几条请求, 并确保每条请求之间有儿秒钟的间隔.还应该限制对站点的访间总次数, 以防止环路的出现 | |
| (4)容忍存在环路、熏复和其他问题 | |
| 处理所有返回代码 | 必须做好处理所有HTTP状态码的准备, 包括各种重定向和错误码。还应该对这些代码进行记录和监视.如果某站点出现大量不成功的结果, 就应该对其进行调查。可能是很多URL过期了, 或者服务器拒绝向机器人提供这些文档 |
| 规范URL | 试诸将所有URL都转化为标准形式来消除常见的别名 |
| 积极地避免环路的出现 | 努力地检测并避免环路的出现。将操纵爬虫的过程当作一个反馈回路。应该将问题的结果和解决方法回馈到下一次爬行中, 使爬虫在每次迭代之后都能表现得更 |
| 监视陷阱 | 有些环路是故意造成的恶意环路. 这些环路可能很难检测。有的站点会带有一些怪异的URL, 要监视对这类站点进行的大量访问。这种情况可能就是陷阱 |
| 维护一个黑名单 | 找到陷阱、环路、故障站点和不希望机器人访问的站点时, 要将其加人一个黑名单, 不要再次访问这些站点 |
| (5)可扩展性 | |
| 了解所需空间 | 享先通过数学计算明确你要解决的问题规摸有多大. 你可能会对应用程序完成一项机器人任务所需的内存规模感到非常吃惊, 这是由Web庞大的规模造成的 |
| 了解所需带宽 | 了解你有多少网络带宽可用, 以及在要求的时间内完成机器人任务所需的带宽大小。监视网络带宽的实际使用情况。你很可能会发现输出带宽(请求)要比输入带宽(响应)小得多。通过对网络使用情况的监视, 可能还会找到一些方法来更好地优化你的机器人, 通过更好地使用其TCP连接更好地利用网络带宽 |
| 了解所需的时间 | 了解机器人完成其任务所需花费的时间, 检查这个进度是否与自己的估计相符. 如果机器人的耗费与自己的估计相去甚远, 可能就会有问题, 需要进行调查 |
| 分而治之 | 对大规模的爬行来说, 很可能需要使用更多的硬件来完成这项工作, 可以使用带有多个网卡的大型多处理器服务器, 也可以使用多台较小的计算机共同配合工作 |
| (6)可靠性 | |
| 彻底测试 | 在将机器人放出去之前. 要对其进行彻底的内部测试. 作好非现场测试准备时, 要先进行几次小型的处女航。收集大量结果井对性能和内存使用情况进行分析, 估计一下它们会怎样累积成较大问题 |
| 检查点 | 所有严谨的机器人都要保存其进展的快照, 出现故障时可以从那里重新开始。故障总是存在的:你会发现一些软件的bug, 硬件也会出故障. 大规模机器人不能在每次出现这种情况时都从头开始. 一开始就要设计检查点/熏启机制 |
| 故障恢复 | 预测故障的发生. 对机器人进行设计、使其能够在发生故障时继续工作 |
| (7)公共关系 | |
| 做好准备 | 机器人可能会让很多人感到困惑. 要作好快速响应其询问的准备。制定一个Web页面政策声明, 对机器人进行描述, 其中包括创建robots.txt文件的详细指南 |
| 充分理解 | 有些与你联系, 讨论机器人问题的人是了解情况并赞成的, 有些人则很幼稚. 少数人会异常愤怒. 有些人看起来好像都要发疯了。去争辩机器人的努力有多么重要通常是没什么效果的. 向他们解释拒绝机器人访问标准,如果他们仍然很不高兴, 就立即将投诉者的URL从爬行列表中删除. 并将其加人黑名单 |
| 积极响应 | 大多数不满意的网管都只是不太了解机器人. 如果你能够进行迅速且专业的响应,90%的投诉都会很快消失. 另一方面, 如果你等好几天才响应.而机器人在继续访问这个站点, 你面对的就将是一个非常愤怒的对手 |
六. 搜索引擎
1. 大格局
2. 现代搜索引擎结构
3. 全文索引
图9-8显示了三份文档和相应的全文索引。全文索引列出了包含每个单词的文档。
比如:
4. 发布查询请求
5. 对结果进行排序, 井提供查询结果
一旦搜索引擎通过其索引得到了查询结果, 网关应用程序会获取结果, 并将其拼成结果页面提供给终端用户。
6. 欺诈
七. 更多信息
更多有关Web客户端的信息, 请参见下列资料。
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/207893.html原文链接:https://javaforall.net
