TypeError: __init__()参数'fieldnames'多值错误的原因与解决
Hey there! Let's break down that TypeError you're hitting with the csv module and get your scraped data saved to CSV smoothly.
What's Causing That Error?
The TypeError: __init__() got multiple values for argument 'fieldnames' almost always happens when you mess up the parameter order or accidentally pass the fieldnames argument twice when initializing csv.DictWriter.
Here's the core issue: the csv.DictWriter constructor expects its first positional argument to be an open file object, and the second to be your list of fieldnames. If you flip those two, or pass fieldnames both as a positional argument and a keyword argument, Python gets confused—like you're telling it the same thing twice in conflicting ways.
For example, these wrong approaches would trigger the error:
# Wrong: Fieldnames first, file object second (reverse order) writer = csv.DictWriter(fieldnames_list, my_csv_file) # Wrong: Duplicate fieldnames argument writer = csv.DictWriter(my_csv_file, fieldnames_list, fieldnames=fieldnames_list)
How to Fix It
Let's walk through a corrected version of your code, tailored to your web scraping workflow. I'll fill in the gaps where your code cut off, so you can adapt it to your actual target URL and data extraction logic:
from urllib.request import urlopen as uReq from bs4 import BeautifulSoup as soup import csv # Replace with your actual target URL my_url = 'https://www.your-target-website.com' # Step 1: Fetch and parse the webpage uClient = uReq(my_url) page_html = uClient.read() uClient.close() page_soup = soup(page_html, "html.parser") # Step 2: Extract your data (replace this with your actual scraping logic) # Example: Let's say you're scraping product names and prices products = page_soup.findAll("div", {"class": "product-card"}) scraped_data = [] for product in products: name = product.find("h3").text.strip() price = product.find("span", {"class": "price"}).text.strip() scraped_data.append({"product_name": name, "product_price": price}) # Step 3: Write to CSV correctly # Define your column names fieldnames = ["product_name", "product_price"] # Open the file (use newline='' to avoid extra blank lines on Windows) with open('scraped_data.csv', 'w', newline='', encoding='utf-8') as csvfile: # Correct initialization: file object first, then fieldnames writer = csv.DictWriter(csvfile, fieldnames=fieldnames) # Write the header row and all your data writer.writeheader() writer.writerows(scraped_data)
Key Things to Remember:
- Parameter Order Matters: Always pass the open file object as the first argument to
csv.DictWriter, followed by your fieldnames (either as a positional argument or usingfieldnames=for clarity). - Avoid Extra Blank Lines: Adding
newline=''when opening the file is a best practice recommended by the Python csv module docs—it prevents unwanted empty lines in your CSV on Windows. - Handle Encoding: Using
encoding='utf-8'ensures any special characters (like accented letters or non-English text) from your scrape are saved correctly.
If you were considering csv.writer instead of csv.DictWriter, note that csv.writer doesn't take a fieldnames argument at all—you'd just pass the file object, then manually write the header row if needed. But DictWriter is perfect here since you're likely storing scraped data as dictionaries.
内容的提问来源于stack exchange,提问作者H D

