scala 在抓取网站进行分析时,无法从分页数据中获取所需数据

5m1hhzi4  于 9个月前  发布在  Scala
关注(0)|答案(1)|浏览(128)

我刮一个网站的分析目的,使用请求验证令牌在其有效载荷。我正在使用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意味着它没有给出实际数据,而是移动到某个其他页面。

cnwbcb6i

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文件和服务条款。
下面是一个修改过的代码片段,可能会对您有所帮助:

val browser = JsoupBrowser()

// Get the homepage
val homepageDoc = browser.get("example.com")
val requestVerificationToken = homepageDoc >> element("input[name='__RequestVerificationToken']") >> attr("value")

// Post form data
val formData = Map(
  "searchtype" -> "C",
  "__RequestVerificationToken" -> requestVerificationToken
)
val doc = browser.post(url, formData)

// Prepare next page form data
val nextPageFormData = Map(
  "undefined" -> "",
  "sortby" -> "",
  "stype" -> "a",
  "pidx" -> "2",
  "__RequestVerificationToken" -> requestVerificationToken // Include the token if needed
)

// Get next page
val nextPageDoc = browser.post(url, nextPageFormData)

如果这不起作用,请在浏览分页数据时仔细检查浏览器发出的请求(使用浏览器开发人员工具),并在代码中尽可能模仿它们。

相关问题