【问题标题】:scraping table from a website result as empty从网站结果中抓取表格为空
【发布时间】:2021-06-19 12:23:01
【问题描述】:

我正在尝试用标签刮掉主表:

<table _ngcontent-jna-c4="" class="rayanDynamicStatement">

来自使用'BeautifulSoup'库的以下网站,但代码返回空[],而打印汤返回html字符串并且请求状态为200。我发现当我使用浏览器'检查元素'工具时,我可以看到表格标签但在“查看页面源代码”中,未显示作为“app-root”标签一部分的表格标签。 (你看到&lt;app-root&gt;&lt;/app-root&gt; 是空的)。此外,网页组件中没有“json”文件可以从中提取数据。请帮助我如何抓取表格数据。

import urllib.request
import pandas as pd
from urllib.parse import unquote
from bs4 import BeautifulSoup
yurl='https://www.codal.ir/Reports/Decision.aspx?LetterSerial=T1hETjlDjOQQQaQQQfaL0Mb7uucg%3D%3D&rt=0&let=6&ct=0&ft=-1&sheetId=0'
req=urllib.request.urlopen(yurl)
print(req.status)
#get response
response = req.read()
html = response.decode("utf-8")
#make html readable
soup = BeautifulSoup(html, features="html")
table_body=soup.find_all("table")
print(table_body)

【问题讨论】:

  • 它是 scrape 不是 scrap
  • @baduker 是的,你是真的。换了个词。

标签: python python-3.x beautifulsoup


【解决方案1】:

表格在源HTML 中,但有点隐藏,然后由JavaScript 渲染。它位于&lt;script&gt; 标记之一中。这可以用bs4 定位,然后用regex 解析。最后,表格数据可以转储到json.loads,然后转储到pandas.csv 文件,但由于我不懂波斯语,你必须看看它是否有用。

仅通过查看一些值,我认为是。

哦,这可以做到没有 selenium

方法如下:

import pandas as pd
import json
import re

import requests
from bs4 import BeautifulSoup

url = "https://www.codal.ir/Reports/Decision.aspx?LetterSerial=T1hETjlDjOQQQaQQQfaL0Mb7uucg%3D%3D&rt=0&let=6&ct=0&ft=-1&sheetId=0"
scripts = BeautifulSoup(
    requests.get(url, verify=False).content,
    "lxml",
).find_all("script", {"type": "text/javascript"})

table_data = json.loads(
    re.search(r"var datasource = ({.*})", scripts[-5].string).group(1),
)

pd.DataFrame(
    table_data["sheets"][0]["tables"][0]["cells"],
).to_csv("huge_table.csv", index=False)

这会输出一个大文件,如下所示:

【讨论】:

  • @Vova,你是什么意思?
  • 反正很好的解决方案,没见过这样的!
  • 谢谢@Vova,非常感谢。
  • @baduker 是一个很好的解决方案,我没有在要设置样式的源代码的其他地方找到“数据源”变量,这意味着表格在服务器端进行了样式设置。顺便说一句,我可以阅读“table_data”并将其更改为类似于网页中显示的格式。
  • 正如我所说,它有点隐藏,但没有那么多。如果您发现我的解决方案有用,请考虑接受它。 stackoverflow.com/help/someone-answers
【解决方案2】:

可能不是最好的解决方案,但在无头模式下使用 webdriver,您可以获得所有您想要的:

from bs4 import BeautifulSoup

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

option = Options()
option.add_argument('--headless')
url = 'https://www.codal.ir/Reports/Decision.aspx?LetterSerial=T1hETjlDjOQQQaQQQfaL0Mb7uucg%3D%3D&rt=0&let=6&ct=0&ft=-1&sheetId=0'
driver = webdriver.Chrome(options=option)
driver.get(url)
bs = BeautifulSoup(driver.page_source, 'html.parser')
print(bs.find('table'))
driver.quit()

【讨论】:

  • 我知道 selenium,但它是一个对测试和模拟有用的库,我期待找到其他方法。
  • 我不急于快速解决,如果您发现其他更好的抓取方法,不胜感激。
【解决方案3】:

看起来您尝试获取的元素是由一些 JavaScript 代码呈现的。您需要使用 Selenium 之类的东西来获得完全呈现的 HTML。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-01
    • 2019-01-16
    • 1970-01-01
    • 2017-10-16
    • 1970-01-01
    • 2022-07-10
    • 2022-01-23
    • 1970-01-01
    相关资源
    最近更新 更多