【问题标题】:Web scraping python not returning any contentWeb抓取python不返回任何内容
【发布时间】:2019-04-27 11:08:15
【问题描述】:

我正在尝试从“https://data.lacity.org/A-Safe-City/Crime-Data-from-2010-to-Present/y8tr-7khq”进行网络抓取。具体来说,在 div class= "socrata-table freeze-columns" 下,所有数据列名称和数据列描述。但是,我编写的代码似乎不起作用(它没有返回任何东西?)

import requests
from bs4 import BeautifulSoup
url = "https://data.lacity.org/A-Safe-City/Crime-Data-from-2010-to-Present/y8tr-7khq"
page = requests.get(url)
print(page.status_code)
soup=BeautifulSoup(page.content,'html.parser')


for col in soup.find_all("div", attrs={"class":"socrata-visualization-container loaded"})[0:1]:
   for tr in col.find_all("div",attrs={"class":"socrata-table frozen-columns"}):
      for data in tr.find_all("div",attrs={"class":"column-header-content"}):
        print(data.text)

我的代码错了吗?

【问题讨论】:

    标签: python web-scraping beautifulsoup


    【解决方案1】:

    页面是动态加载的,数据集是分页的,这意味着使用浏览器自动化来检索,这很慢。您可以使用一个 API。它具有允许您批量返回结果的参数..

    阅读 API 文档here。这将是一种更有效、更可靠的数据检索方式。

    使用limit 确定一次检索的#条记录;使用offset 参数开始下一批新记录。此处调用示例。

    由于它是一个查询,您实际上可以像使用 SQL 查询一样定制其他参数来检索所需的结果集。这也意味着您可能可以编写一个非常快速的初始查询来从数据库中返回记录计数,您可以使用它来确定批处理请求的终点。

    您可以编写一个基于类的脚本,使用多处理并更有效地获取这些批次。

    import requests
    import pandas as pd
    from pandas.io.json import json_normalize
    
    response  = requests.get('https://data.lacity.org/api/id/y8tr-7khq.json?$select=`dr_no`,`date_rptd`,`date_occ`,`time_occ`,`area_id`,`area_name`,`rpt_dist_no`,`crm_cd`,`crm_cd_desc`,`mocodes`,`vict_age`,`vict_sex`,`vict_descent`,`premis_cd`,`premis_desc`,`weapon_used_cd`,`weapon_desc`,`status`,`status_desc`,`crm_cd_1`,`crm_cd_2`,`crm_cd_3`,`crm_cd_4`,`location`,`cross_street`,`location_1`&$order=`date_occ`+DESC&$limit=100&$offset=0')
    data = response.json()
    data = json_normalize(data)
    df = pd.DataFrame(data)
    print(df)
    

    JSON 响应中的示例记录:

    【讨论】:

    • 哦,哇,这太容易了,我想我会改用api,非常感谢。请问偏移参数是如何工作的?数据集有超过 180 万行,如果我将每批限制为 100,000,这意味着偏移量 = 18?
    • 再次感谢。我已经接受了你的回答,即使它不是对我最初问题的直接回答。我将阅读 API,我想我理解了偏移量是如何工作的(即起点)。不幸的是,我仍然无法编写基于类的脚本。
    • 查看文档。我的猜测是它指定了记录检索的起始位置。因此,如果您在第一次运行时检索了 1000 条记录,则指定 1001 从下一条记录开始。你应该这样做,但这通常是逻辑。
    • 你总是可以写一个循环来批量处理。您可以遍历包含您插入主请求 URL 的各种参数的列表(列表?)。我将使用我应该指定的重新动态加载来更新答案。
    • 是的,它偏移了下一批的起点。再次感谢!
    【解决方案2】:

    如果您查看页面源代码 (ctrl + U),您会注意到没有 <div class = "socrata-table frozen-columns"> 这样的元素。这是因为您要删除的内容是动态添加到页面中的。看看这个问题:web scraping dynamic content with pythonWeb scraping a website with dynamic javascript content

    【讨论】:

      【解决方案3】:

      这是因为数据在页面加载后由 ReactJs 动态填充。

      如果您通过请求下载它,您将看不到数据。

      您需要使用selenium 网络驱动程序,打开页面并处理所有JavaScript。然后你就可以得到你期望的数据了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-08-27
        • 2021-10-15
        • 1970-01-01
        • 2015-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多