使用Python+BeautifulSoup+Pandas实现爬虫结果输出到对应CSV文件
代码问题修正方案
原有代码核心问题
- csv.DictReader是一次性迭代器,第一次遍历读取url后迭代器已经耗尽,第二次读取outputfile只会得到空列表
- 爬取函数内部共用全局data变量,所有url的爬取结果会混存,且仅在所有循环结束后执行一次爬取,只爬了最后一个url
- 输出时传入了整个outputs列表作为文件名,不符合参数要求
修正后完整代码
import requests from bs4 import BeautifulSoup import pandas as pd import csv # 单独定义爬取函数,不要放在循环内,返回当前url的所有爬取数据 def scrape_it(base_url): data = [] current_url = base_url while True: page = requests.get(current_url, headers={'Cookie': 'ResultsPerPage=100'}) soup = BeautifulSoup(page.text, 'html.parser') # 提取当前页报告数据 reports = soup.find_all("tr", {"class": ["SearchTableRowAlt", "SearchTableRow"]}) for report in reports: data.append({ 'title': report.find('a', class_='linkTitle').text, 'price': report.find('div', class_='resultPrice').text, 'date_author': report.find('div', class_='textGrey').text.replace(' | published by: TechNavio', ''), 'detail_link': report.a['href'] }) # 检查是否有下一页 next_ele = soup.find_all(class_="standardLinkDkBlue")[-1] if 'next' not in next_ele.string: print(f"{base_url} 所有页面爬取完成") break current_url = next_ele['href'] return data if __name__ == '__main__': # 一次性读取url和对应输出文件名,避免迭代器耗尽问题 task_list = [] with open('inputs.csv', newline='') as csvfile: reader = csv.DictReader(csvfile) for row in reader: task_list.append({ 'url': row['url'], 'output': row['outputfile'] }) # 逐个处理每个爬取任务,单独输出对应文件 for task in task_list: crawl_data = scrape_it(task['url']) myOutput = pd.DataFrame(crawl_data) myOutput.to_csv(task['output'], header=False, index=False)
关键修改说明
- 把递归爬取下一页改成了循环实现,避免递归深度过高出现报错
- 爬取函数内部单独维护每个url的爬取数据,执行完单个任务就直接写入对应文件,不会出现数据混存、覆盖的问题
- 读取inputs.csv时一次性把url和对应输出文件名成对存入任务列表,不会出现迭代器耗尽读不到输出文件名的问题
- 输出时直接传入当前任务对应的输出文件名,不需要处理整个列表
内容的提问来源于stack exchange,提问作者Michael Wiz
相关产品推荐
相关产品推荐

