咨询ProgrammingError: SQL语法错误near '['的含义及代码修复方案
首先,咱们直接戳破核心问题:你遇到的这个SQL语法错误,完全是因为错误地把Python列表转成字符串后拼接SQL语句导致的。咱们一步步拆解:
你把存储数据的列表all_var转成了字符串a_v = str(all_var),然后遍历这个字符串的每个字符(Python里遍历字符串就是逐个取字符)。比如all_var原本是类似[(200000, 'Dublin', 'Semi-Detached', 2, 3)]的列表,转成字符串后会变成"[(200000, 'Dublin', 'Semi-Detached', 2, 3)]",当你遍历a_v时,第一个var就是[,这就导致执行的SQL变成了:
INSERT INTO DaftTable(price, location, type, bathrooms, bedrooms) VALUES[
MySQL当然不认识[,直接触发语法错误。
除此之外,你的代码还有几个隐性问题,咱们一起修复:
问题1:SQL拼接的错误姿势
永远不要直接把Python数据转成字符串硬拼进SQL——除了语法错误,还会带来SQL注入风险。正确做法是用MySQL Connector的参数化查询。
问题2:BeautifulSoup选择器语法错误
你写的find("a {\"class\":\"PropertyInformationCommonStyles__addressCopy--link\"}")完全错了,find方法的第一个参数是标签名,第二个参数是属性字典,应该写成find("a", {"class":"PropertyInformationCommonStyles__addressCopy--link"}),同理bath_num的选择器也犯了同样的错。
问题3:URL格式化失效
你的my_url里没有format占位符,"https://www.daft.ie/ireland/property-for-sale/? offset=20".format(page)根本不会替换掉20,应该把20换成{},还要去掉offset前的空格(避免无效URL)。
修复后的完整代码
from bs4 import BeautifulSoup from urllib.request import urlopen as uReq import mysql.connector p_list = [] n_list = [] h_list = [] ba_list = [] be_list = [] all_var = [] # 修复URL格式化:添加占位符,移除无效空格 for page in range(20, 300, 20): my_url = "https://www.daft.ie/ireland/property-for-sale/?offset={}".format(page) uClient = uReq(my_url) page_html = uClient.read() uClient.close() soup = BeautifulSoup(page_html, "html.parser") # 注意:如果网站结构更新,这个class可能需要调整,建议用浏览器开发者工具确认 listings = soup.findAll("div", {"class":"FeaturedCardPropertyInformation__detailsContainer"}) for container in listings: # 提取价格,增加异常处理避免非数字价格崩溃 price_text = container.div.div.strong.text.strip() price_clean = price_text.replace('AMV: €', '').replace('Reserve: €', '').replace(',', '') try: price = int(price_clean) except ValueError: # 跳过"Price on Application"这类非数字价格的条目 continue p_list.append(price) # 修复BeautifulSoup选择器语法,增加空值判断 location_tag = container.div.find("a", {"class":"PropertyInformationCommonStyles__addressCopy--link"}) if not location_tag: continue location = location_tag.text.strip() n_list.append(location) house_tag = container.div.find("div", {"class":"QuickPropertyDetails__propertyType"}) if not house_tag: continue house = house_tag.text.strip() h_list.append(house) # 修复bath_num的选择器 bath_num_tag = container.div.find("div", {"class":"QuickPropertyDetails__iconCopy--WithBorder"}) if not bath_num_tag: continue try: bath_num = int(bath_num_tag.text.strip()) except ValueError: continue ba_list.append(bath_num) bed_num_tag = container.div.find("div", {"class":"QuickPropertyDetails__iconCopy"}) if not bed_num_tag: continue try: bed_num = int(bed_num_tag.text.strip()) except ValueError: continue be_list.append(bed_num) all_var.append((price, location, house, bath_num, bed_num)) # 连接数据库 d_b = mysql.connector.connect( host="localhost", user="myaccount", passwd="mypassword", database="database" ) mycursor = d_b.cursor(buffered=True) # 使用参数化批量插入,高效又安全 if all_var: insert_query = """ INSERT INTO DaftTable(price, location, type, bathrooms, bedrooms) VALUES (%s, %s, %s, %s, %s) """ # executemany批量插入比循环execute高效N倍 mycursor.executemany(insert_query, all_var) d_b.commit() print(f"成功插入{mycursor.rowcount}条数据") # 关闭资源 mycursor.close() d_b.close()
关键修改点说明
- 参数化查询:用
executemany批量插入,占位符%s会自动处理字符串引号、转义等问题,彻底避免语法错误和SQL注入。 - 选择器修复:修正了BeautifulSoup的
find调用方式,同时添加空值判断,避免页面结构变化导致程序崩溃。 - 异常处理:增加
try-except处理价格、房间数转整数失败的情况,跳过无效数据。 - URL修正:正确使用format替换offset参数,确保请求的是有效分页URL。
内容的提问来源于stack exchange,提问作者A_Lopez

