从books.toscrape爬取图书评分存入SQLite出现InterfaceError如何解决
错误原因
- 核心触发报错的问题:执行
INSERT INTO BOOKS语句时,你传入的names、prices、rate都是列表类型,SQLite 要求插入的是和字段一一对应的单个值,无法识别列表类型,因此抛出不支持类型的报错。 - 其他逻辑错误:
- 遍历所有图书URL时,每次都请求首页地址,没有使用你提前收集的单本图书URL,爬取到的永远是首页的重复数据
- 内层遍历图书标签时,每次都用
soup.find("article")取第一本图书的信息,和当前遍历的article对象完全不匹配 - 价格字段在表中定义为INTEGER类型,但爬取到的价格是带小数点的字符串,需要转换为数值类型后再插入
- 你创建了CATEGORY表但全程没有使用,属于无效冗余代码
修正后可运行的代码
from bs4 import BeautifulSoup import requests import sqlite3 conn = sqlite3.connect('scraped.db') curs = conn.cursor() # 不需要分类表可以注释掉这行,或者后续补充分类逻辑 # curs.execute(''' CREATE TABLE CATEGORY(Id INTEGER PRIMARY KEY,NAME TEXT)''') # 价格改成REAL类型适配浮点数值 curs.execute(''' CREATE TABLE IF NOT EXISTS BOOKS(Category_Id INTEGER, NAME TEXT,PRICE REAL,RATING TEXT)''') base_url = "http://books.toscrape.com/" def get_soup(url): result = requests.get(url) return BeautifulSoup(result.text, 'html.parser') def get_book_urls_from_page(page_url): soup = get_soup(page_url) book_paths = [x.find("div").find("a").get('href') for x in soup.findAll("article", class_="product_pod")] return ["/".join(page_url.split("/")[:-1]) + "/" + path for path in book_paths] # 收集所有分页地址 pages_urls = [] new_page = "http://books.toscrape.com/catalogue/page-1.html" while requests.get(new_page).status_code == 200: pages_urls.append(new_page) page_num = int(pages_urls[-1].split("-")[1].split(".")[0]) new_page = pages_urls[-1].split("-")[0] + "-" + str(page_num + 1) + ".html" # 收集所有单本图书地址 all_book_urls = [] for page in pages_urls: all_book_urls.extend(get_book_urls_from_page(page)) # 遍历每本图书地址爬取信息入库 for category_id, book_url in enumerate(all_book_urls): soup = get_soup(book_url) # 单本图书页面直接取对应信息即可,不需要遍历article name = soup.find("div", class_="product_main").find("h1").get_text() price = float(soup.find("p", class_="price_color").text[2:]) rating = soup.find("p", class_="star-rating").get('class')[1] curs.execute("INSERT INTO BOOKS VALUES(?,?,?,?)", (category_id, name, price, rating)) conn.commit() conn.close()
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

