无法在输入框中捕获并输入一些动态生成的数字以填充某些结果

Posted

技术标签:

【中文标题】无法在输入框中捕获并输入一些动态生成的数字以填充某些结果【英文标题】:Unable to catch and input some dynamically generated number in an inputbox to populate some result 【发布时间】:2019-11-08 00:33:41 【问题描述】:

您好,我正在尝试从网站 https://www.nsekra.com/ 抓取信息。我们需要从下拉列表中选择Non-Individual,然后输入PAN 为AAAHA0064Q,以及每次访问或打开网站时生成一个随机数的captcha number。之后,我们需要按下Search 按钮,以便获取所需的信息。

import requests
from bs4 import BeautifulSoup

resp = requests.get('https://www.nsekra.com/')
soup = BeautifulSoup(resp.text,'lxml')
dictinfo = i['name']:i.get('value','') for i in soup.select('input[name]')

# trying to enter PAN as 'AAAHA0064Q'
dictinfo['txtPan']='AAAHA0064Q'

# trying to get captcha number & passing to textbox
captcha_number = soup.select_one("#lblDynamicCode").text
print('Fetched Catpcha No. -> ',captcha_number);
dictinfo['txtImageBox'] = captcha_number

# passsing pan no. & captcha number to the request method  
resp2 = requests.post('https://www.nsekra.com/',data=dictinfo)
soup2 = BeautifulSoup(resp2.text,'lxml')
name = soup2.select_one('#lblKra_name').text
print('KRA Name : '+name)

输出

print('Fetched Catpcha No. -> ',s);

获取的 Catpcha 编号 -> 757205

print(soup2.prettify());

print('KRA Name : '+name)

KRA 名称:&nbsp

预期输出

KRA 名称:CVL KRA

如您所见,我可以获取验证码,但是当我尝试将其传递给网站时,每次访问网站时它都会重新生成新号码。所以基本上,上面的代码确实获取了验证码,但是在访问网站时,会生成新的数字,而不是新的数字,而是传递旧的或以前的数字,而不是访问网站时的当前数字。如何获取并利用动态生成的数字来获取我感兴趣的结果?我喜欢坚持使用 requests 库来完成它。

【问题讨论】:

我建议使用selenium,而不是BeatifulSoup,您可以轻松地与页面交互。 只用request就可以了,看我的回答。 @MITHU - 非常感谢 MITHU。 没问题@David。这个问题对我来说似乎也很有趣,这就是我决定悬赏的原因。谢谢。 【参考方案1】:

重要的部分是在会话中执行您的请求,而不是将输入中找到的所有参数作为数据发布(只有btnAllKRA 很重要):

import requests
from bs4 import BeautifulSoup

with requests.Session() as session:     # <---- IMPORTANT!

    resp = session.get('https://www.nsekra.com/')
    soup = BeautifulSoup(resp.text,'lxml')
    dictinfo = i['name']:i.get('value','') for i in soup.select('input[name]')

    # trying to enter PAN as 'AAAHA0064Q'
    dictinfo['txtPan']='AAAHA0064Q'

    # trying to get captcha number & passing to textbox
    captcha_number = soup.select_one("#lblDynamicCode").text
    print('Fetched Catpcha No. -> ',captcha_number);
    dictinfo['txtImageBox'] = captcha_number

    for k in [*dictinfo.keys()]:        # <---- IMPORTANT!
        if k.lower().startswith('btn') and k.lower() != 'btnallkra':
            del dictinfo[k]

    # passsing pan no. & captcha number to the request method
    resp2 = session.post('https://www.nsekra.com/',data=dictinfo)
    soup2 = BeautifulSoup(resp2.text,'lxml')

    name = soup2.select_one('#lblKra_name').text
    print('KRA Name : '+name)

打印:

Fetched Catpcha No. ->  314885
KRA Name : CVL KRA

【讨论】:

太完美了!!!系统不能让我马上奖励这个赏金。我得等12个小时。谢谢。 @MITHU 很高兴为您提供帮助。让我们等一下:) @AndrejKesely - 非常感谢 Andrej。我不希望它可以通过请求库来完成。你能解释一下(代码中的第二个重要部分del dictinfo[k],BtnPrint、btnkra、btnCancel 是如何影响结果的。因为由于您使用的是 SESSION,所以它应该在该会话本身中给出输出,因此删除以上三个键如何影响输出。 @David 我以前刮过这些类型的网站,我认为它们在运行 ASP.NET 的服务器上。我的理解是,服务器需要知道哪个按钮被按下(这意味着哪个btn在请求中),并据此服务器将进行内部路由。 @AndrejKesely - 好的,非常感谢 Andrej,所以我猜之前所有的按钮都在请求中传递了。【参考方案2】:

虽然您已经明确提到您想使用 requests 模块来获取该名称,但我还是愿意为您提供与硒相关的解决方案,以防万一有类似问题的人遇到此帖子以寻求任何解决方案.

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

link = "https://www.nsekra.com/"

def get_name(driver,url):

    driver.get(url)
    select = Select(wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "select[id='ddlKyc']"))))
    select.select_by_visible_text("Non-Individual")

    wait.until(EC.presence_of_element_located((By.ID,"txtPan"))).send_keys("AAAHA0064Q")
    dynamic_number = wait.until(EC.presence_of_element_located((By.ID,"lblDynamicCode"))).text
    wait.until(EC.presence_of_element_located((By.ID,"txtImageBox"))).send_keys(dynamic_number)
    wait.until(EC.presence_of_element_located((By.ID, "btnAllKRA"))).click()

    name = wait.until(EC.presence_of_element_located((By.ID, "lblKra_name"))).text
    print(name)

if __name__ == "__main__":
    driver = webdriver.Chrome()
    wait = WebDriverWait(driver,10)
    try:
        get_name(driver,link)
    finally:
        driver.quit()

输出:

CVL KRA

【讨论】:

【参考方案3】:

对第一个 GET 请求的响应包括一些看起来像安全令牌的 cookie。

因此,假设您在使用 python 时根据您的许可协议使用该站点,您可以在第二个请求中包含相同的 cookie,例如使用Session:

with requests.Session() as session:
    resp = session.get(...)
    ...
    resp2 = session.post(...)

【讨论】:

在修改赏金问题之前,我通过创建一个会话走这条路,然后像你建议的那样重复使用它们,但这并没有帮助我获取所需的结果。

以上是关于无法在输入框中捕获并输入一些动态生成的数字以填充某些结果的主要内容,如果未能解决你的问题,请参考以下文章

Tkinter-在输入框中输入后未返回用户输入

在动态 php mysql 查找中丢失输入字符

如何从模块内的 modalDialog 动态生成和捕获用户输入?

动态生成的表单无法正常工作

如何通过Js实现点击一组复选框,动态添加1个input输入框,输入框中自动填充所选复选框的内容呢?

Excel VBA文本框以填充组合框