Python Web 抓取内网在登录后不会继续

Python Web scraping Intranet won't proceed after login

我是 Python webscraping 的新手,休息 api, html。首先,我不得不说,有许多与我的问题相似的不同解决方案。但我的问题是关于 Intranet 网站的,与其他任何问题都不相似。几天以来,我几乎研究了每个 link,在所有失败的尝试之后,我正在 post 回答这个问题,因为我没有得到任何帮助。请考虑我的努力,不要将其标记为重复或不需要的问题。

  1. 背景要求:

我正在尝试自动化内部网站中的某些列 ID。为此,我使用 python Web scraping 来获取特定列的 ID 列表,然后将它们设置为打开或关闭。例如,如果一个 ID 与我在本地的 excel 文件中的 ID 匹配,我应该在该 Intranet 门户中打开或关闭状态列(与该 ID 平行)。为此,我正在使用 requests 库。而且这个内网网站只有在我给具体的用户名、密码认证后才能正常运行

  1. 问题:

问题是我无法登录到该 Web 门户,然后使用 Web scraping 导航到我需要的页面。我得到的只是 'View source code' html 脚本的一部分作为输出。即使我直接抓取我想要的导航网页(有效负载作为用户名、密码),我仍然只得到这个主页数据。谁能建议我如何解决 scraping 登录后我想要的网页中的数据?我不确定我是否能够成功登录,因为我只是得到 html response <200> 作为状态码登录。我理解是找到网站的成功代码。但是后来我无法看到登录后的任何数据。抓取的数据是登录前的首页

  1. 结果:

输出抓取数据:

<!doctype html>
<html lang="en" ng-app="lm.login.application" class="lm-scroll-bar html-overflow" ng-strict-di>
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge">
    <meta charset="utf-8">
    <meta name="HandheldFriendly" content="True">
    <meta name="viewport"
          content='width=device-width,height=device-height, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, target-densitydpi=device-dpi'/>
    <link rel="icon" href="../favicon.ico?ui-version=12.0.40.12" type="image/x-icon">
    <title>Login</title>
    <link rel="stylesheet" href="/ui/generated/webpack/authpoint.beaf402df60c88783fc6.min.css?ui-version=12.0.40.12"/>
    <script>
        var lmSession = {
            buildVersion: '76',
            redirectTarget: 'https\x3A\x2F\x2F<intanet_webportal_>\x2Dprod.<intanet_address_>group.net\x2Fui\x2F',
            language: 'english',
            userLanguageCode: 'en',
            isMLU: false,
            isProduction: true,
            isExternalAuthModeEnabled: false,
            productBrandEditionDisplayName: 'EDITION PLACEHOLDER',
            logLevel: 'error',
            siteParams: {"LOGIN_PAGE_NAME_LABEL": ""},
            loginNotice: '\x3Cdiv\x20style\x3D\x22font\x2Dsize\x3A120\x25\x3Bcolor\x3Ared\x3B\x22\x3EZur\x20erstmaligen\x20Nutzung\x20seit\x20dem\x20Update\x20Strg\x20\x2B\x20F5\x20dr\xFCcken\x20um\x20den\x20Seiten\x20Cache\x20zu\x20l\xF6schen.\x3C\x2Fdiv\x3E\x3Cbr\x3EWelcome\x20using\x20\x3Ca\x20href\x3D\x22http\x3A\x2F\x2F<intanet_webportal_>.<intanet_address_>group.net\x2F\x22\x20style\x3D\x22background\x2Dcolor\x3A\x23ffffa0\x22\x3ETAEE\x20Next\x3C\x2Fa\x3E\x20via\x20<intanet_webportal_>.\x3Cbr\x3E\x3Ca\x20href\x3D\x22https\x3A\x2F\x2Fvts4.<intanet_address_>group.net\x2Fsites\x2Ftundaee\x2F<intanet_webportal_>\x2FDocuments\x2FTAEE\x2DNext\x2520\x2D\x2520Disclaimer.pdf\x3FWeb\x3D1\x22\x20style\x3D\x22background\x2Dcolor\x3A\x23ffffa0\x22\x3EErkl\xE4rung\x20zum\x20Datenschutz\x2FPrivacy\x20notice\x3C\x2Fa\x3E\x20\x3Cbr\x3E\x3Ca\x20href\x3D\x22https\x3A\x2F\x2Fvts4.<intanet_address_>group.net\x2Fsites\x2Ftundaee\x2F<intanet_webportal_>\x2FDocuments\x2FNUTZUNGSBEDINGUNGEN\x2520TAEE\x2DNext.pdf\x22\x20style\x3D\x22background\x2Dcolor\x3A\x23ffffa0\x22\x3ENutzungsbedingungen\x3C\x2Fa\x3E'
        };
    </script>
</head>

<body ng-controller="lm.login.application.controller">

<noscript>
    <div class="browser-misconfig-alert">LM requires that JavaScript be enabled in your browser</div>
</noscript>

<script src="/ui/generated/webpack/authpoint.17231e2531a66bfe2e17.min.js"></script>

<div class="ng-cloak" class="web-ui-login-main-wrapper">
    <div class="web-ui-login-wrapper">
        <ng-include src="'login-app.html?ui-version=12.0.40.12'"></ng-include>
    </div>
</div>

</body>
</html>


Process finished with exit code 0`

尽管我进行了所有尝试,但我只能刮到这么多。但是登录后没有登录或导航到下一页并获取我想要的字段。

尝试过的方法:

使用所有这些方法,我只得到上面显示的 html 数据。我的网站没有 csrf 令牌。它只有 xsrf header.

有人可以解释一下我哪里失败了,我如何登录、导航然后通过 python scraping 获取数据。由于内部限制,我只能使用 Python。我明白,200 作为状态代码的响应并不意味着它已使用给定的用户 ID 和密码成功登录。

任何帮助将不胜感激。百万吨谢谢!!这将是一个救命问题

由于是内网门户,为了不泄露数据,我改了名字。希望大家理解

你的硒方法对我来说似乎是正确的。这是您的代码的略微调整版本。请检查元素选择器。主要思想是使用 WebDriverWait 等待您需要的每个元素,并在执行任何操作之前滚动到它。对于按钮,使用 EC.element_to_be_clickable 代替 EC.presence_of_element_located 可能很有用。

检索到一些容器元素后,您可以使用 print(element.get_attribute('innerHTML')) 进行调试。

from selenium import webdriver 
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

# delay for selenium web driver wait
DELAY = 30

# create selenium driver
chrome_options = webdriver.ChromeOptions()
#chrome_options.add_argument('--headless')
#chrome_options.add_argument('--no-sandbox')
driver = webdriver.Chrome('<<PATH_TO_CHROMEDRIVER>>', options=chrome_options)

# open web page
driver.get('<<URL>>')

# maximize window
driver.maximize_window()

# wait for username input, scroll to it, enter username
username = WebDriverWait(driver, DELAY).until(EC.presence_of_element_located((By.ID, "inputusername")))
driver.execute_script("arguments[0].scrollIntoView();", username)
username.send_keys("user") 

# wait for password input, scroll to it, enter password
password = WebDriverWait(driver, DELAY).until(EC.presence_of_element_located((By.ID, "password")))
driver.execute_script("arguments[0].scrollIntoView();", password)
password.send_keys("password")

# wait for submit button, scroll to it, click it
submit = WebDriverWait(driver, DELAY).until(EC.presence_of_element_located((By.ID, "login")))
driver.execute_script("arguments[0].scrollIntoView();", submit)
submit.click()

# quit driver
#driver.quit() 

如果有任何问题,添加 HTML 登录页面的来源(使用之前描述的 element.get_attribute('innerHTML') 方法)会很有帮助。