【问题标题】:Extracting population by using web scraping in Python from dynamic graph在 Python 中使用网络抓取从动态图中提取人口
【发布时间】:2024-04-26 19:30:01
【问题描述】:

我的任务是遍历https://www.unitedstateszipcodes.org/23022/#stats 中的所有美国邮政编码,并从图中每年的数字下方提取。

此链接是一个邮政编码区域的示例。在我将它们全部提取出来后,我需要将它们放入 Pandas 数据框中(这很容易),尝试查看其他帖子,但似乎无法解决这个问题。

查看了html中的元素,但很不清楚。

import requests
from bs4 import BeautifulSoup
import pandas as pd

url = 'https://www.unitedstateszipcodes.org/23022/#stats'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'}

soup = BeautifulSoup(requests.get(url, headers=headers).content, 'html.parser')

match = soup.findAll('tr')
print(match)

years = ['Historical ' + str(year) for year in range(2005, 2019)]

columns = ['ZIP Code', *years]
df = pd.DataFrame(columns=columns)

【问题讨论】:

  • 邮政编码太多了。是否有您感兴趣的特定邮政编码列表?
  • 我需要从 2005 年到 2018 年在该网站(美国)中列出的每个邮政编码 @QHarr
  • 邮政编码不是从数据库中提取的,您必须付费才能访问吗?我查看了来自simplemaps.com/data/us-zips 的免费列表,数量巨大,但我看到很多在针对您所需的数据源进行尝试时没有数据。我正在尝试寻找一种公平的方式来获取数据,而不会让服务器淹没在成千上万的请求中。
  • 我从一家即将工作的公司接到了任务。因此以合法的方式对其进行检查和验证。
  • 您不能为数据转储获得报酬吗? unitedstateszipcodes.org/zip-code-database

标签: python web-scraping beautifulsoup


【解决方案1】:

我不想淹没服务器。看起来它根据邮政编码查询后台数据库的数据,并且并非所有邮政编码都有相关数据。如果您可以确定合适的范围,则将其用于可迭代对象(例如列表)中。除了针对所有邮政编码之外的简单尝试会产生大量请求,您需要开始考虑批量请求、随时间传播、添加暂停和切换到异步请求。

可以从响应文本中的 JavaScript 对象中提取图表数据,并使用 json 库进行解析。我假设所有回复的年份是一致的。

import requests
import pandas as pd
import re, json

results = []
columns = ['zip']

with requests.Session() as s:
    
    s.headers = {'User-Agent':'Mozilla/5.0'}
    
    for code in range(23022, 23025): 
        
        url = f'https://www.unitedstateszipcodes.org/{code}/#stats'
        r = s.get(url)
        
        try:
            res = re.search(r'var data = (\[.*\])', r.text).group(1)
            data = json.loads(res)[0]['values']
            values = [i['y'] for i in data]
            values.insert(0, code)
            results.append(values)
            
            if values and len(columns) == 1:
                columns.extend([i['x'] for i in data])
        except:
            pass

df = pd.DataFrame(results, columns = columns)
print(df)

【讨论】:

  • 感谢您抽出宝贵的时间,我的任务只是将其从图表中提取出来,这就是为什么我尝试使用漂亮的汤,否则会使用 uszipcode python 库
  • 这就是图表值的来源。一个脚本标签。我只是使用正则表达式来更容易地获取适当的项目。在循环中打印data,您将看到x、y 图表值。如果您查看页面源代码,或者在浏览器中禁用 JS,您将看到一个空图表,因为需要运行 JS 来填充图表。
最近更新 更多