当前位置: 首页 > 知识库问答 >
问题:

使用beautifulsoup从页面中刮取表格时,找不到表格

单于奇略
2023-03-14

我一直想把桌子从这里刮下来,但在我看来BeautifulSoup找不到桌子。

我写道:

import requests
import pandas as pd
from bs4 import BeautifulSoup
import csv

url = "http://www.payscale.com/college-salary-report/bachelors?page=65" 
r=requests.get(url)
data=r.text

soup=BeautifulSoup(data,'xml')
table=soup.find_all('table')
print table   #prints nothing..

基于其他类似的问题,我假设HTML在某种程度上被破坏了,但我不是专家…我找不到答案:(Beautiful soup缺少一些html表标签)、(从网站提取表)、(使用Beautiful soup刮表),甚至(Python+Beautiful soup:从网页刮表)

多谢了!

共有3个答案

慕容昊焜
2023-03-14

数据位于JavaScript变量中,您应该找到js文本数据,然后使用regex提取它。当您得到数据时,它是json列表对象,其中包含900+school dict,您应该使用json模块将其加载到python列表obejct。

import requests, bs4, re, json

url = "http://www.payscale.com/college-salary-report/bachelors?page=65"
r = requests.get(url)
data = r.text
soup = bs4.BeautifulSoup(data, 'lxml')
var = soup.find(text=re.compile('collegeSalaryReportData'))
table_text = re.search(r'collegeSalaryReportData = (\[.+\]);\n    var', var, re.DOTALL).group(1)
table_data = json.loads(table_text)
pprint(table_data)
print('The number of school', len(table_data))

外出:

 {'% Female': '0.57',
  '% High Job Meaning': 'N/A',
  '% Male': '0.43',
  '% Pell': 'N/A',
  '% STEM': '0.1',
  '% who Recommend School': 'N/A',
  'Division 1 Basketball Classifications': 'Not Division 1 Basketball',
  'Division 1 Football Classifications': 'Not Division 1 Football',
  'Early Career Median Pay': '36200',
  'IPEDS ID': '199643',
  'ImageUrl': '/content/school_logos/Shaw University_50px.png',
  'Mid-Career Median Pay': '45600',
  'Rank': '963',
  'School Name': 'Shaw University',
  'School Sector': 'Private not-for-profit',
  'School Type': 'Private School, Religious',
  'State': 'North Carolina',
  'Undergraduate Enrollment': '1664',
  'Url': '/research/US/School=Shaw_University/Salary',
  'Zip Code': '27601'}]
The number of school 963
米丰
2023-03-14

虽然这将找不到不在r.text中的表,但您要求BeautifulSoup使用xml解析器,而不是html.parser,因此我建议将该行更改为:

soup=BeautifulSoup(data,“html.parser”)

您将遇到的一个问题是什么是所谓的“客户端呈现的”网站和服务器呈现的网站。基本上,这意味着通过requests模块或curl(例如)从基本html请求获得的页面与在web浏览器中呈现的内容不同。这方面的一些常见框架是React和Angular。如果您检查要刮取的页面的源,它们的几个html元素上都有data-react-ids。角页面的常见区别是具有前缀ng的类似元素属性,例如ng-ifng-bind。您可以在Chrome或Firefox中通过各自的开发工具看到页面的源代码,这些开发工具可以通过键盘快捷键Ctrl+Shift+I在任一浏览器中启动。值得注意的是,并不是所有的React&Angular页面都只是客户端呈现的。

为了获得这类内容,您需要使用像Selenium这样的无头浏览器工具。关于使用Selenium和Python进行web刮取的资源很多。

湛鸿
2023-03-14

您正在解析HTML但您使用了XML解析器。
您应该使用soup=BeautifulSoup(data,“html.parser”)
您必需的数据在script标记中,实际上没有table标记。因此,您需要在script中查找文本。
注意:如果您使用的是Python 2.x,请使用“htmlparser”而不是“html.parser”。

这是密码。

import csv
import requests
from bs4 import BeautifulSoup

url = "http://www.payscale.com/college-salary-report/bachelors?page=65" 
r=requests.get(url)
data=r.text

soup=BeautifulSoup(data,"html.parser")
scripts = soup.find_all("script")

file_name = open("table.csv","w",newline="")
writer = csv.writer(file_name)
list_to_write = []

list_to_write.append(["Rank","School Name","School Type","Early Career Median Pay","Mid-Career Median Pay","% High Job Meaning","% STEM"])

for script in scripts:
    text = script.text
    start = 0
    end = 0
    if(len(text) > 10000):
        while(start > -1):
            start = text.find('"School Name":"',start)
            if(start == -1):
                break
            start += len('"School Name":"')
            end = text.find('"',start)
            school_name = text[start:end]

            start = text.find('"Early Career Median Pay":"',start)
            start += len('"Early Career Median Pay":"')
            end = text.find('"',start)
            early_pay = text[start:end]

            start = text.find('"Mid-Career Median Pay":"',start)
            start += len('"Mid-Career Median Pay":"')
            end = text.find('"',start)
            mid_pay = text[start:end]

            start = text.find('"Rank":"',start)
            start += len('"Rank":"')
            end = text.find('"',start)
            rank = text[start:end]

            start = text.find('"% High Job Meaning":"',start)
            start += len('"% High Job Meaning":"')
            end = text.find('"',start)
            high_job = text[start:end]

            start = text.find('"School Type":"',start)
            start += len('"School Type":"')
            end = text.find('"',start)
            school_type = text[start:end]

            start = text.find('"% STEM":"',start)
            start += len('"% STEM":"')
            end = text.find('"',start)
            stem = text[start:end]

            list_to_write.append([rank,school_name,school_type,early_pay,mid_pay,high_job,stem])
writer.writerows(list_to_write)
file_name.close()

这将在CSV中生成您所需的表。完成后别忘了关闭文件。

 类似资料:
  • BeautifulSoup尝试(替换最后3行) 这不会输出任何东西--在这个页面上,找到一些标签(divs、spans等)可以工作,但另一些则不行。在本例中,它没有按照预期找到带有game_info的表。

  • 我对使用python有点陌生,我接到了一个任务,需要从表中抓取数据。我也不太懂html。我以前从来没有这样做过,花了几天时间研究各种刮桌子的方法。不幸的是,所有的例子都是一个看起来比我所处理的更简单的网页布局。我尝试了很多不同的方法,但没有一种方法允许我选择所需的表数据。 下面网页底部的“每日水位”选项卡下的表怎么刮? url=https://apps.wrd.state.or.us/apps/g

  • 我正在尝试刮网页,在那里我需要解码整个表到一个数据帧。我正为此使用漂亮的汤。在某些标记中,有一些标记没有任何文本。但这些值会显示在网页上的特定span标记中。 下面的代码对应于该网页, 但是,这个标记中显示的值是。我试着删掉它,但我收到的是空短信。 如何刮这个价值使用美丽的汤。 URL:https://en.tutiempo.net/climate/ws-432950.html 下面给出了我的用于

  • 上面的代码只显示了三个表单,而在Chrome的页面中显示了13个 元素。但如果我查看页面源代码( Chrome中),源代码只显示BeautifulSoup刮过的三种形式。 我怎样才能刮掉所有的表格?

  • 问题内容: 我正在尝试使用BeautifulSoup提取此数据表的第一和第三列。通过查看HTML,第一列具有一个标记。感兴趣的另一列具有作为标记。无论如何,我所能获得的就是带有标签的列的列表。但是,我只想要文本。 已经是列表,所以我不能使用。我不确定如何以另一种形式获得第一列的清单。 问题答案: 您可以尝试以下代码: 如您所见,代码只是连接到url并获取html,BeautifulSoup找到第一

  • 我一直在使用Python和Selenium从特定的州健康网页中获取数据,并将该表输出到本地CSV。 我在其他几个州使用类似的代码取得了很多成功。但是,我遇到了一种状态,即使用看起来像R的东西来创建动态仪表板,而我无法使用常规方法真正访问这些仪表板。 我花了很多时间梳理StackOverflow。我已经检查了是否有一个iframe可以切换,但是,我只是没有看到页面上iframe中我想要的数据。 使用