【问题标题】:Failed to capture a certain field from different containers out of a webpage using requests无法使用请求从网页的不同容器中捕获某个字段
【发布时间】:2021-08-02 18:12:40
【问题描述】:

我创建了一个脚本,使用请求从webpage 获取数据。该页面中的内容是高度动态的,但是我在观察开发工具中的网络活动时发现了一个可用的 api。除了DMEPOS Accredited For 的值之外,我几乎可以从每个容器中获取所有字段。如何使用请求捕获它?

这是我尝试过的(目前它会打印名称):

import requests
from pprint import pprint

link = 'https://www.abcop.org/mxt/FacilityApi/GetFacilities?PostCode=99999&Radius=10'

with requests.Session() as s:
    s.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36'
    res = s.get(link)
    for item in res.json()['ResultSet']:
        print(item['org_name'])

【问题讨论】:

  • 您需要更多详细信息吗?这和你所追求的差不多吗?

标签: python python-3.x web-scraping python-requests


【解决方案1】:

DMEPOS 认可的设置由不同 API 调用中的标志('0' - 否,'1' - 是)指示。在该调用中,组织名称和结果计数与您提供的网页链接相匹配。另一个 API 调用给出了一组不同的结果。

大多数这些标志的映射(一对不存在,在响应中设置为“1”,但在页面上不存在,例如amc_app_orth_off_the_shelf_flag_ext)存在于 JavaScript 文件中,您可以构建您的自己查找将标志映射到值;如 DMEPOS Accredited 网页上所见。要构建此查找,您可以正则表达式输出包含页面到标志映射的 JavaScript 对象,

然后使用 hjson 处理未加引号的键,并编写自己的函数来反转键、值映射。由于同一个键可以有多个值,因此与该键关联的值是一个列表,具有相同键的项目将添加到该列表中。

然后,当您向返回带有标志的列表的 API 端点发出请求时,您可以使用查找来返回页面上看到的认证值。

import requests
import re
import hjson

def print_dmepos_accredited(item: dict):

    result = []

    print(item['org_name'])

    for k, v in item.items():

        if k in lookup:
            if isinstance(v, list):
                if any([int(i) for i in v]):
                    result.extend(lookup[k])
            else:
                if int(v):
                    result.extend(lookup[k])
    print(result)


def create_lookup(data: dict) -> dict:
    d = {}

    for k, v in data.items():
        for i in v:
            if i in d:
                d[i].append(k)
            else:
                d[i] = [k]
    # d['amc_app_orth_off_the_shelf_flag_ext'] = ['Unknown']  # not in js file
    # d['amc_app_orth_prefabricated_flag_ext'] = ['Unknown']  # not in js file

    return d


with requests.Session() as s:
    r = s.get(
        'https://www.abcop.org/mxt/FacilityApi/GetFacilities?PostCode=10001&Radius=10').json()
    res = s.get(
        'https://www.abcop.org/ResourcePackages/ABC/modules/abc-directory/dist/main.js?v=2021-03-04T10:56:formatted').text
    data = hjson.loads(re.search(r'accredTypes:(.*?\})', res).group(1))

    lookup = create_lookup(data)

    for item in r['ResultSet']:
        print_dmepos_accredited(item)
        print()

【讨论】:

  • 对不起@QHarr,我没有注意到你提供了解决问题的方法。
【解决方案2】:

我在js file 中发现了DMEPOS Accredited For,格式如下:

function(t){
       t.exports=JSON.parse('
              ["Orthotics","Prosthetics","Pedorthics","Assistants","Technician","Orthotic Fitting","Mastectomy","Therapeutic Shoe Fitting"]')},
function(t){
       t.exports=JSON.parse('
              ["Orthotics","Prosthetics","Pedorthics","Mastectomy","Central Fab","Ocular","DME","Pharmacy","Non-Custom Shoes"]')}

但我还没有真正找到他们如何在网站中加载这些数据。

【讨论】:

    猜你喜欢
    • 2020-08-30
    • 2021-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多