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

Python 使用beautifulsoup从页面中刮取表格时,找不到表格,python,web-scraping,beautifulsoup,Python,Web Scraping,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'

我一直想把桌子刮下来 但在我看来,美丽的乌苏似乎找不到任何桌子

我写道:

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在某种程度上被破坏了,但我不是专家。。 无法在以下内容中找到答案: (), (), (),甚至()


非常感谢

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

soup=BeautifulSoup(数据,'html.parser')

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


为了获得此类内容,您需要使用无头浏览器工具,如。有很多关于Selenium和Python的web抓取资源。

您正在解析
html
,但您使用了
xml
解析器。
您应该使用
soup=beautifulsou(数据,“html.parser”)

您需要的数据在
script
标记中,实际上没有
标记。因此,您需要在
脚本
中查找文本
注意:如果您使用的是Python2.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中生成所需的表。完成后不要忘记关闭文件。

数据位于JavaScript变量中,您应该找到js文本数据,然后使用正则表达式提取它。当您获得数据时,它是一个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))
输出:


我会打印
数据
,看看您是否在该页面中找到了表格。谢谢@metama。我这么做了-唯一的问题是:B组找不到它。。另外,如果在这种情况下找桌子不是办法,那么你会怎么做?谢谢页面中没有表标记。所有表格信息都在脚本标签中。您需要从表格中获取哪些信息??谢谢@KhairulBasarRofi。我需要表格,因为它是。在CSV将是很好的..谢谢你@Khairul你的代码(几乎)工程。我不得不删除newline=“”,因为python认为它不会将此参数引入open()函数。当我查找以了解它时,我看到它是为Python3引入的一个新参数。我说的是这一行:
file\u name=open(“table.csv”,“w”,newline=”“)
这非常有用->谢谢。我用python 3.5编写了代码,很抱歉我不知道这是python 3中的一个新参数,否则我会提到的@Oba2311别担心@Khairul你确实解决了问题!因此检查-谢谢。我再次回顾了你的回答,以加深我的学习。我意识到我不确定为什么以及如何选择
html.parser
,因为在BS文档
LXML
中,建议使用其他方法来处理html。我看了看这里:@metame在他的回答中也没有回答这个问题。谢谢@oba2311实际上,“html.parser”和“lxml”之间并没有太大区别。
 {'% 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