如何实现网页解析中除建筑外的其他筛选条件(如带阳台)的数据抓取?
如何实现网页解析中除建筑外的其他筛选条件(如带阳台)的数据抓取?
嘿,我看你遇到的问题核心是API参数不匹配——你当前的代码只适配了「建筑ID」这类object类型的筛选,但像「带阳台」这种属于option类的筛选,后端API需要的参数结构完全不一样哦!
问题根源
你之前的代码里,请求payload固定用了'filter[object]': object_id,这只对应“按建筑筛选”的场景。但当你选“带阳台”这类筛选时,网站实际发送的请求参数是filter[option][](对应URL里的option%5B%5D=23),而不是filter[object]。用错参数名,自然拿不到数据啦!
解决方案:让筛选参数动态化
我们可以重构代码,让它支持不同类型的筛选条件,甚至可以组合多个筛选规则。下面是修改后的完整代码:
import requests import pandas as pd base_link_url = "https://etalongroup.ru" # Base URL for apartment links def fetch_data(action: str, filter_dict: dict, offset: int, limit: int) -> dict: url = f"https://etalongroup.ru/bitrix/services/main/ajax.php?action={action}" # 基础请求参数 payload = { 'haveItem': 'true', 'limit': limit, 'offset': offset } # 动态添加筛选条件,适配不同类型的筛选(object/option等) for key, value in filter_dict.items(): payload[f'filter[{key}]'] = value response = requests.post(url, data=payload) return response.json() def get_data(action: str, filter_dict: dict, max_offset: int, limit: int = 50) -> list: result = [] offset = 0 while offset < max_offset: response_json = fetch_data(action, filter_dict, offset, limit) # 增加响应结构检查,避免报错 if not response_json.get('data') or len(response_json['data']) == 0: break item_list = response_json['data'][0].get('itemList', []) if not item_list: break for item in item_list: flat_info = { 'id': item.get('id'), 'img': base_link_url + item.get('img', ''), 'price': item.get('price'), 'priceTotal': item.get('priceTotal'), 'area': item.get('area'), 'floor': item.get('floor'), 'title': item.get('title'), 'link': base_link_url + item.get('link', ''), 'deliveryName': item.get('deliveryName'), 'isBooked': item.get('isBooked'), # 把筛选条件存入结果,方便后续区分 **{f'filter_{k}': v for k, v in filter_dict.items()} } result.append(flat_info) offset += limit return result # 示例1:抓取建筑ID为16的公寓 print("Fetching data for building ID 16...") building_data = get_data( action='etalongroup:filter.FlatFilter.getFlatList', filter_dict={'object': 16}, max_offset=700 ) df_building = pd.DataFrame(building_data) print(f"Total flats for building 16: {len(df_building)}") # 示例2:抓取带阳台(option ID为23)的公寓 print("\nFetching data for flats with balcony (option ID 23)...") balcony_data = get_data( action='etalongroup:filter.FlatFilter.getFlatList', filter_dict={'option[]': 23}, max_offset=1000 # 根据实际数据量调整 ) df_balcony = pd.DataFrame(balcony_data) print(f"Total flats with balcony: {len(df_balcony)}") # 示例3:组合筛选(建筑16里带阳台的公寓) print("\nFetching data for building 16 + balcony...") combined_data = get_data( action='etalongroup:filter.FlatFilter.getFlatList', filter_dict={'object': 16, 'option[]': 23}, max_offset=500 ) df_combined = pd.DataFrame(combined_data) print(f"Total flats in building 16 with balcony: {len(df_combined)}") # 导出数据到CSV # df_balcony.to_csv('flats_with_balcony.csv', index=False)
关键修改点说明
- 动态筛选参数:用
filter_dict代替固定的object_id,可以灵活传入不同类型的筛选条件——比如{'object':16}对应建筑筛选,{'option[]':23}对应阳台筛选。 - 参数格式适配:
option[]是网站API要求的格式(对应URL里的option%5B%5D),requests会自动帮我们编码成正确的URL格式。 - 健壮性提升:增加了响应结构检查,避免因为返回数据异常导致代码崩溃。
- 筛选条件留存:把筛选参数存入结果字典,方便后续分析时区分不同筛选批次的数据。
额外小技巧
如果不知道某个筛选条件对应的参数名,可以打开浏览器开发者工具(F12),切换到「Network」标签,手动选择筛选条件后,查看发送的POST请求里的Form Data,就能找到对应的filter[xxx]参数啦!
备注:内容来源于stack exchange,提问作者Danny Mxxre
相关产品推荐
相关产品推荐

