【问题标题】:Trouble in fetching data from next pages using post requests in Python在 Python 中使用 post 请求从下一页获取数据时遇到问题
【发布时间】:2021-11-03 08:31:23
【问题描述】:

我正在尝试从以下网站 抓取 数据。这些表被分成不同的页面,但所有页面都使用相同的 url。我正在使用 Requests、pandas 和 BeautifulSoup 来解析 HTML 代码,我只能抓取初始表,但我想要所有表中的全部数据。

注意我只尝试使用 Pandas、Beautifulsoup 和 requests ....not Selenium 注意此网站显示特定时间的数据,页面范围从 0 到 9 或有时 10,15

我编写了程序,但它只提取第一个表,我想从所有页面中提取数据。请帮帮我

import requests
from bs4 import BeautifulSoup
import pandas as pd

params = {                   #Console
    "pos": " ",
    "stats": " ",
    "type": " "
}

data = {                                # Network --> Request 
    "__EVENTTARGET" : "grdMWCG@ctl29",   #grdMWCG$ctl29$ctl00
    '__EVENTARGUMENT': "",    #'FireCommand:grdMWCG$ctl29;PageSize;1000',
   #'__VIEWSTATE' : "qI7kN0JsQhV3qLHXe45eUTDT1YiA+R/k6VJkLSCL++BAyoKgHIgYgPbr+q/NsFwQ5BHwqPkAeV25qNkOUOoz3vfYWD1d77cTyCM4sJKinGsyC9FfPkqSEPT5lEOhkP41a3Xo1GywCFbapgM83hXY5/Lu/RrQAjLNdEUwsg+dj/WHn+aE",
    '__VIEWSTATEGENERATOR': "00145D45",
    '__VIEWSTATEENCRYPTED':""
   #'__EVENTVALIDATION': "41pWf5gO9W1jt4YKQK30WKaHlv3pGh+kaJAUpRk5MkyZqR/AauHgJ5YEFWg9DjwtQNxwXWSH6QbNwjgOjgyI2fkLOtSbFu0r9JuA+dXqtmvLUuIHECQv8HNH+8a1c179u6QvlBSsSMzIvpfJNPPu7ats04coyA3FHDghbZPDWqREQeq5"
}

def main(url):
    with requests.Session() as req:
      # r = req.get(url, params=params)
        r = req.get(url)
        soup = BeautifulSoup(r.content, 'html.parser')
        data['__VIEWSTATE'] = soup.find("input", id="__VIEWSTATE").get("value")
        data['__EVENTVALIDATION'] = soup.find(
            "input", id="__EVENTVALIDATION").get("value")
        #r = req.post(url, params=params, data=data)
        r = req.post(url ,  data=data)
        df = pd.read_html(r.content, attrs={
                          'id': 'grdMWCG'})[0]          #Table id  #grdMWCG
        #df.drop(df.columns[3], axis=1, inplace=True)
        print(df)
        df.to_csv("ccil.csv", index=False)


main("https://www.ccilindia.com/OMMWCG.aspx")

【问题讨论】:

  • 请不要通过破坏您的帖子为他人增加工作量。通过在 Stack Exchange (SE) 网络上发帖,您已根据 CC BY-SA license 授予 SE 分发内容的不可撤销权利(即无论您未来的选择如何)。根据 SE 政策,分发非破坏版本。因此,任何破坏行为都将被撤销。请参阅:How does deleting work? …。如果允许删除,则帖子下方左侧有一个“删除”按钮,但仅在浏览器中,而不是移动应用程序中。

标签: python python-3.x python-requests


【解决方案1】:

因此,要从所有页面获取数据,您需要请求它们。

查看手动点击页面时调用的代码,发现会调用__doPostBack函数:

<a href="javascript:__doPostBack('grdMWSG$ctl29$ctl01','')" style="color:#35496A;">2</a>

此函数将在表单字段中输入值并提交表单。

function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}

页码存储在函数调用的值中:

grdMWSG$ctl29$ctl01 // page 2

您应该创建一个遍历页面数量的循环并发出请求并提取数据。

此代码将请求第一页,提取页数,更新帖子字段并从所有页面请求数据。

它只打印数据。如果你想保存它,你必须添加 pd.to_csv 调用。

import requests
from bs4 import BeautifulSoup
import pandas as pd

params = {                   #Console
    "pos": " ",
    "stats": " ",
    "type": " "
}

data = {                             
    "__EVENTTARGET" : "",
    '__EVENTARGUMENT': '',  
    "__VIEWSTATE" : "",
    "__VIEWSTATEGENERATOR": "",
    "__VIEWSTATEENCRYPTED": "",
    "__EVENTVALIDATION": "",
    
    
}


# Update the data Fields with new Values 
# For fields that can't be found the exception can be ignored 
def updateData(response):
    global data 
    soup = BeautifulSoup(response.content, 'html.parser')
    for i in data: 
        try:
            data[i] = soup.find("input", id=i).get("value")
        except:
             pass
            #print(i)

def main(url):
    global data 
    targetString = "grdMWCG$ctl29$ctl0"
    with requests.Session() as req:
        r = req.get(url)
        df = pd.read_html(r.content, attrs={
                      'id': 'grdMWCG'})[0]          

        # Print Table of First Page 
        print(df)
        
        # get the last element of the last colum, where the current page count is stored 
        # The 26 is a magic number I don't know if it will always be 26
        pageLength = int(df[0][26][-1])
        
        updateData(r)
        
        for pageNumber in range(1,pageLength):
            data["__EVENTTARGET"] = targetString+str(pageNumber)
            r = req.post(url ,  data=data)
            _df = pd.read_html(r.content, attrs={
                          'id': 'grdMWCG'})[0]          
            updateData(r)        
            df = df.append(_df)
        df.to_csv("ccild.csv", index=False)


main("https://www.ccilindia.com/OMMWCG.aspx")

【讨论】:

  • 先生,我非常感谢您。请帮助我,如何打印 CSV 中的所有数据,我试过了,但它只打印最后一页的数据。
  • 您应该将数据存储在某处,然后保存到 csv。如果您在每次打印调用后添加保存调用,它将覆盖旧的 csv 文件
  • 我已经改好保存了
  • 完美运行,非常感谢您的帮助。事实上,许多开发人员告诉我,如果没有 selenium,就无法从该网站提取数据。我也尝试过使用 selenium 的程序,它可以工作,但速度很慢。真的非常感谢。
  • @TechBro 是否有问题或其他事情不起作用?
猜你喜欢
  • 1970-01-01
  • 2013-09-27
  • 2014-01-01
  • 2021-02-21
  • 1970-01-01
  • 2021-08-19
  • 1970-01-01
  • 2020-10-18
  • 1970-01-01
相关资源
最近更新 更多