【问题标题】:Beautiful soup pareses in some cases but not in others. Why?在某些情况下,美丽的汤会瘫痪,但在其他情况下则不然。为什么?
【发布时间】:2014-06-13 09:57:57
【问题描述】:

我正在使用 Beautiful Soup 从 HTML 文件中解析出一些 JSON。 基本上,我使用的是从 LinkedIn 搜索结果中获取所有员工资料。 但是,由于某种原因,它不适用于拥有超过 10 名员工的公司。 这是我的代码

import requests, json
from bs4 import BeautifulSoup
s = requests.session()

def get_csrf_tokens():
    url = "https://www.linkedin.com/"
    req = s.get(url).text

    csrf_token = req.split('name="csrfToken" value=')[1].split('" id="')[0]
    login_csrf_token = req.split('name="loginCsrfParam" value="')[1].split('" id="')[0]

    return csrf_token, login_csrf_token


def login(username, password):
    url = "https://www.linkedin.com/uas/login-submit"
    csrfToken, loginCsrfParam = get_csrf_tokens()

    data = {
        'session_key': username,
        'session_password': password,
        'csrfToken': csrfToken,
        'loginCsrfParam': loginCsrfParam
    }

    req = s.post(url, data=data)
    print "success"

login(USERNAME PASSWORD)
def get_all_json(company_link):
    r=s.get(company_link)
    html= r.content
    soup=BeautifulSoup(html)
    html_file= open("html_file.html", 'w')
    html_file.write(html)
    html_file.close()
    Json_stuff=soup.find('code', id="voltron_srp_main-content")
    print Json_stuff
    return remove_tags(Json_stuff)
def remove_tags(p):
    p=str(p)
    return p[62: -10]

def list_of_employes():
    jsons=get_all_json('https://www.linkedin.com/vsearch/p?f_CC=2409087')
    print jsons
    loaded_json=json.loads(jsons.replace(r'\u002d', '-'))
    employes=loaded_json['content']['page']['voltron_unified_search_json']['search']['results']
    return employes
def get_employee_link(employes):
    profiles=[]
    for employee in employes:
        print employee['person']['link_nprofile_view_3']
        profiles.append(employee['person']['link_nprofile_view_3'])
    return profiles , len(profiles)

print get_employee_link(list_of_employes())

它不适用于现有的链接;但是它适用于该公司搜索:https://www.linkedin.com/vsearch/p?f_CC=3003796

编辑: 我很确定这是 get_all_json() 函数的错误。如果 你看一下,它不能正确获取超过 10 名员工的公司的 JSON。

【问题讨论】:

  • 你使用的是lxml还是html5lib?或者只是 Python 标准库 HtmlParser?我不知道您的具体情况,但 lxml 和 html5lib 都比 HtmlParser 更强大。
  • 我不确定。我如何检查以及如何更改它,因为我认为这可能是我的问题。
  • lxml 和 html5lib 不在标准库中,因此如果您没有专门安装其中任何一个,您可能正在使用标准库 HtmlParser。如果不确定,可以通过“import lxml”或“import html5lib”进行检查。如果你得到一个 ImportError,你就没有它们。
  • 好的,我都试过了,结果一样

标签: python json parsing beautifulsoup


【解决方案1】:

这是因为结果是分页的。您需要在以下位置获取 json 数据中定义的所有页面:

data['content']['page']['voltron_unified_search_json']['search']['baseData']['resultPagination']['pages']

pages 是一个列表,对于公司2409087 它是:

[{u'isCurrentPage': True, u'pageNum': 1, u'pageURL': u'http://www.linkedin.com/vsearch/p?f_CC=2409087&page_num=1'}, 
 {u'isCurrentPage': False, u'pageNum': 2, u'pageURL': u'http://www.linkedin.com/vsearch/p?f_CC=2409087&page_num=2', u'page_number_i18n': u'Page 2'}, 
 {u'isCurrentPage': False, u'pageNum': 3, u'pageURL': u'http://www.linkedin.com/vsearch/p?f_CC=2409087&page_num=3', u'page_number_i18n': u'Page 3'}]

这基本上是您需要克服并获取数据的 URL 列表。

这是您需要做的(省略登录代码):

def get_results(json_code):
    return json_code['content']['page']['voltron_unified_search_json']['search']['results']

url = "https://www.linkedin.com/vsearch/p?f_CC=2409087"
soup = BeautifulSoup(s.get(url).text)

code = soup.find('code', id="voltron_srp_main-content").contents[0].replace(r'\u002d', '-')
json_code = json.loads(code)

results = get_results(json_code)

pages = json_code['content']['page']['voltron_unified_search_json']['search']['baseData']['resultPagination']['pages']
for page in pages[1:]:
    soup = BeautifulSoup(s.get(page['pageURL']).text)
    code = soup.find('code', id="voltron_srp_main-content").contents[0].replace(r'\u002d', '-')
    json_code = json.loads(code)
    results += get_results(json_code)

print len(results)

它为https://www.linkedin.com/vsearch/p?f_CC=2409087 打印25 - 正是您在浏览器中看到的数量。

【讨论】:

  • 您好,感谢您的回答。它有帮助,但它并没有真正解决这个问题。我的代码现在的问题是漂亮的汤没有得到 JSON
  • @JONPON 好的,我提供的代码实际上是在解析它,它是工作代码,看起来就像你想要的那样......
  • 是的。但这是考虑到您获得了 JSON 代码。你看,我的代码的问题是当我使用超过 10 名员工的链接时,BS4 没有得到 JSON。而不是返回由 标记包围的 json,它只返回 ,其中没有任何内容。
【解决方案2】:

原来是默认的 BeautifulSoup 解析器有问题。 我通过这样做将其更改为 html5lib:

在控制台中安装

pip install html5lib

并在第一次创建汤对象时更改您选择的解析器类型。

soup = BeautifulSoup(html, 'html5lib')

这在BeautifulSoup docs here中有记录

【讨论】:

    猜你喜欢
    • 2010-10-12
    • 2015-12-24
    • 2019-12-27
    • 1970-01-01
    • 2018-08-27
    • 2018-05-17
    • 2019-02-25
    • 2019-01-29
    • 1970-01-01
    相关资源
    最近更新 更多