我刮一个网站的分析目的,使用请求验证令牌在其有效载荷。我正在使用JsoupBrowser()(库:“net.ruippeixotog”%%“scala-scraper”%“3.0.0”)和Scala(版本2.13.1)。
首先,我向主页发送一个获取请求,并从主页获取请求验证令牌。
代码:
val browser = JsoupBrowser()
val homepageDoc = browser.get("example.com")
val requestVerificationToken = homepageDoc >> element("input[name='__RequestVerificationToken']") >> attr("value")
然后使用这个requestVerificationToken我向主页发送请求以获取数据。
代码:
val formData = Map(
"searchtype" -> "C",
"__RequestVerificationToken" -> requestVerificationToken
)
val doc = browser.post(url, formData)
在这个阶段,一切都运行良好。但是数据是分页的,并且在此请求的有效负载中没有请求验证令牌。代码是:
val nextPageFormData = Map(
"undefined" -> "",
"sortby" -> "",
"stype" -> "a",
"pidx" -> "2"
)
val doc = browser.post(url, nextPageFormData)
但这次它没有给出所需的数据,而是给出了一些登录表单。我已经设置了cookie的请求,并试图做同样的事情与cookie,但这也是行不通的。
指导我如何做到这一点,在那里一切都在工作,除了分页。
**更新:**我已经尝试使用HTTP进行上述工作。
代码:
implicit val actorSystem: ActorSystem = ActorSystem()
implicit val executionContext: ExecutionContextExecutor = actorSystem.dispatcher
val browser = JsoupBrowser()
val homepageDoc = browser.get("example.com")
val requestVerificationToken = homepageDoc >> element("input[name='__RequestVerificationToken']") >> attr("value")
val url = "searchpage.com"
val postBody = "undefined=&sortby=&stype=a&pidx=2"
val request = HttpRequest(HttpMethods.POST, url, Seq(RawHeader("__requestverificationtoken",requestVerificationToken)), HttpEntity(ContentTypes.`application/x-www-form-urlencoded`, postBody))
val responseFuture = Http(actorSystem).singleRequest(request)
responseFuture
.onComplete {
case Success(res) => println(res)
Unmarshal(res.entity.toStrict(5 seconds)).value.map { result =>
val htmlStr = result.data.utf8String
val browser = JsoupBrowser()
val doc = browser.parseString(htmlStr)
println(doc)
}
case Failure(e) => println(e)
}
输出量:
HttpResponse(302 Found,List(Cache-Control: private, Location: /BFS/Online/Account/Index?ReturnUrl=%2FBFS%2Fonline%2FNotarySearch%2FGetNotaryListWithOutCriteria, x-frame-options: SAMEORIGIN, x-frame-options: SAMEORIGIN, Access-Control-Allow-Origin: *, Date: Tue, 25 Jul 2023 12:42:00 GMT, Via: 1.1 dca1-bit16043, Strict-Transport-Security: max-age=63072000),HttpEntity.Strict(text/html; charset=UTF-8,214 bytes total),HttpProtocol(HTTP/1.1))
JsoupDocument(<html>
<head>
<title>Object moved</title>
</head>
<body>
<h2>Object moved to <a href="/BFS/Online/Account/Index?ReturnUrl=%2FBFS%2Fonline%2FNotarySearch%2FGetNotaryListWithOutCriteria">here</a>.</h2>
</body>
</html>)
它给出302意味着它没有给出实际数据,而是移动到某个其他页面。
1条答案
按热度按时间cnwbcb6i1#
在使用Web抓取时,您似乎面临着一个常见的挑战,特别是在处理身份验证和分页时。
您收到的带有
302 Found
状态代码的响应指向登录页面,这清楚地表明服务器需要某种会话信息或其他验证信息来处理请求。以下是一些帮助你进步的想法:
1.请确保正确处理cookie:当您发出初始请求时,服务器可能会设置一些cookie,这些cookie需要与后续请求一起发送回来,以维护会话。在您的代码片段中,不清楚您是否正确地处理了cookie,因此请确保使用CookieJar或一些等效机制在会话期间管理cookie。
1.检查网络流量:使用浏览器开发人员工具(大多数浏览器中为F12)查看手动导航分页结果时发出的请求。查看头、请求方法、cookie和发送的任何其他数据,并在代码中复制这些数据。
1.查找隐藏字段:有些网站使用隐藏表单字段来存储请求之间的状态信息。一定要检查HTML源代码中是否有任何隐藏的输入字段,这些字段在发布到下一页时可能是必需的。
1.考虑XHR请求:有时,分页数据是通过AJAX调用(XHR请求)获取的,您可以直接调用这些URL。同样,使用开发人员工具检查网络流量可以帮助您找到这些URL。
1.所有请求使用同一个JsoupBrowser示例:请务必在所有请求中使用相同的
JsoupBrowser
示例,以便保留cookie和其他会话信息。1.校验标题和内容类型:请确保您发送正确的标题并使用正确的内容类型。表单数据的
Content-Type
通常应为"application/x-www-form-urlencoded"
。您可能还需要包含其他头文件,如"User-Agent"
,以模仿真实的浏览器。1.使用适当的身份验证机制:如果站点需要身份验证,请确保您使用的是站点所需的适当身份验证机制,例如OAuth或基本身份验证。
1.尊重网站的robots.txt和服务条款:同样值得注意的是,你应该始终确保你被允许刮你正在使用的网站。查看网站的robots.txt文件和服务条款。
下面是一个修改过的代码片段,可能会对您有所帮助:
如果这不起作用,请在浏览分页数据时仔细检查浏览器发出的请求(使用浏览器开发人员工具),并在代码中尽可能模仿它们。