【问题标题】:BeautifulSoup returns empty list when parsed for linksBeautifulSoup 在解析链接时返回空列表
【发布时间】:2020-07-15 21:26:55
【问题描述】:

我是网络抓取的新手,我正在尝试使用 BeautifulSoup 从网站中提取链接和表格数据。但是,即使网页中有链接,它也不会返回任何内容。我可以通过在浏览器中查看网页来找到链接。

这是我正在使用的代码

from bs4 import BeautifulSoup as soup
from selenium import webdriver

driver = webdriver.Chrome()
url = "http://www.ms2soft.com/tcds/?loc=Txdot&mod=tcds&local_id=57CC441"
driver.get(url)

content = driver.page_source.encode('utf-8').strip()
pageData = soup(content, "html.parser")
links = pageData.find_all('a')

网页给出了达拉斯市的交通数据。我也使用了requestsurllib模块,但没有运气。

【问题讨论】:

  • 哪些链接很多,哪些表也很多!
  • @αԋɱҽԃαмєяιcαη 网页中的任何表格。例如,id 为tblTable1 的表。我无法解析网页上的任何表格数据或链接数据。一点点挖掘告诉我,网页有 Java 脚本,不能直接解析。

标签: python beautifulsoup html-parsing


【解决方案1】:

不幸的是,此特定服务不会向 API 发出任何直接请求 - 这将非常方便,因为这意味着您可以简单地模仿对同一 API 的请求,并且(很可能)返回易于解析的 JSON。

这个页面碰巧使用 ajax 并提供 .asp 文件 - 这意味着服务器执行一些脚本来生成实际的 HTML,然后它会为您提供服务。它也恰好为每个不同的表提供不同的 .asp 文件 - 基本上我是说这不是那么有趣。您可能必须为每个不同的表编写略有不同的解决方案才能获得所需的内容。

这是我想出的一个基础项目。您创建一个requests.Session 来跟踪cookie(在这种情况下,服务器恰好关心会话cookie)。然后,您对要抓取的每个表的 .asp 资源发出实际请求(在我的示例中,我只是抓取 AADT(年平均每日流量)表) - 每个表都有一个唯一的 URL,您可以通过查看浏览器的网络/资源/流量记录器。查看 Google Chrome 开发者工具中的 Query-String / Requests 参数,我选择了一些参数,它们似乎对您要抓取的特定记录很重要。然后我想出了一个粗略的列表理解,以使抓取的数据更具表现力 - 这部分可能会因每个表而有所不同。

def main():

    import requests
    from bs4 import BeautifulSoup
    from itertools import groupby

    session_url = "https://txdot.ms2soft.com/tcds/tsearch.asp"

    session = requests.Session()
    session_response = session.get(session_url)
    session_response.raise_for_status()

    aadt_url = "https://txdot.ms2soft.com/tcds/ajax/tcds_tdetail_aadt.asp"

    params = {
        "offset": "0",
        "agency_id": "97",
        "local_id": "57CC441"
    }

    aadt_response = session.get(aadt_url, params=params)
    aadt_response.raise_for_status()

    soup = BeautifulSoup(aadt_response.content, "html.parser")

    rows = list(list(group) for key, group in groupby([item.find(text=True, recursive=False) for item in soup.find_all("td", {"class": "FormRow"})], key=lambda i: i and i.isprintable()) if key)
    print(rows)

    return 0


if __name__ == "__main__":
    import sys
    sys.exit(main())

输出:

[['2018', '1,482'], ['2017', '1,482', '246', '17'], ['2016', '1,488', '255', '17', '100'], ['2015', '1,199', '155', '13']]
>>> 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-13
    • 2019-12-12
    • 2019-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多