使用bs4和requests抓取多链接数据异常问题咨询
问题根因排查
- 变量覆盖+循环位置错误:
products变量在URL遍历循环内部被重复赋值,每次请求新页面都会覆盖上一页的抓取结果,且打印数据的循环放在了URL遍历结束后,只能拿到最后一次循环的页面数据,无法聚合多页结果。 findAll方法参数使用错误:该方法第一个参数为目标标签名,无法同时传入两个标签名作为前两个参数进行匹配,原写法无法同时识别h2和span两类标签,导致只能抓取到一类字段。- 冗余请求问题:原代码中对同一个URL重复发起了两次
requests.get请求,会浪费请求资源还可能增加被反爬的概率。
修复方案
- 初始化一个空列表放在URL遍历循环外,统一存储所有页面的抓取结果,避免数据被覆盖
- 分别匹配两类标签后按对应关系配对,避免字段顺序混乱
- 去掉冗余请求逻辑,每个页面只发起一次请求
完整可运行代码
import csv import requests from bs4 import BeautifulSoup urls = ['https://www.canada411.ca/search/si/1/kumar/Canada/?pgLen=100','https://www.canada411.ca/search/si/2/kumar/Canada/?pgLen=100'] # 全局存储所有抓取到的联系人数据 all_contacts = [] for url in urls: response = requests.get(url) soup = BeautifulSoup(response.content, "html.parser") # 分别匹配姓名和电话号码标签 name_tags = soup.find_all('h2', class_='c411ListedName') phone_tags = soup.find_all('span', class_='c411Phone') # 按顺序配对姓名和手机号,避免字段对应错误 for name, phone in zip(name_tags, phone_tags): all_contacts.append({ "姓名": name.text.strip(), "电话号码": phone.text.strip() }) # 打印所有抓取结果 for contact in all_contacts: print(f"姓名:{contact['姓名']},电话:{contact['电话号码']}") # 如需导出为CSV可放开下方注释 # with open('联系人数据.csv', 'w', newline='', encoding='utf-8-sig') as f: # writer = csv.DictWriter(f, fieldnames=["姓名", "电话号码"]) # writer.writeheader() # writer.writerows(all_contacts)
内容的提问来源于stack exchange,提问作者Alian Nadeem
相关产品推荐
相关产品推荐

