Python中合并requests与requests-html代码出现冲突如何解决?
问题根因及修复方案
1. 变量作用域冲突修复
你收到的shadows name 'r' from outer scope属于代码规范警告,本身不会直接导致代码运行失败,但属于不规范写法:外层全局作用域定义了存储爬取响应的变量r,add_to_airtable函数内部又定义了存储Airtable接口响应的同名变量r,内部变量会覆盖外部变量的引用。修改方法非常简单:把两处的r改成语义化的不同命名即可,比如函数内改为airtable_resp,爬取部分改为scrape_resp。
2. 代码运行失败的常见原因排查
你提到合并后无法正常运行,大概率不是变量名冲突导致的,优先排查以下问题:
- 谷歌购物页面属于动态渲染页面,requests-html默认只加载静态源码,不会执行JS,你需要在
scrape_resp = session.get(url)之后加一行scrape_resp.html.render()才能拿到动态加载的商品列表 urls.txt读取的每行url默认带末尾换行符,需要用url.strip()处理后再发起请求,否则会请求出错time.sleep(1)当前写在for url循环外,只会执行一次,建议放到循环内每次请求后执行,避免触发谷歌的反爬机制
3. 用requests-html发起Airtable POST请求的可行性
是完全可行的,requests_html.HTMLSession本身继承自requests.Session,原生支持post方法,你甚至可以不用单独导入requests库,直接用已经初始化的session对象调用post方法即可。
修改后的完整代码
from requests_html import HTML, HTMLSession import time AIRTABLE_BASE_ID = "***" AIRTABLE_API_KEY = "***" AIRTABLE_TABLE_NAME = "***" endpoint = f'https://api.airtable.com/v0/{AIRTABLE_BASE_ID}/{AIRTABLE_TABLE_NAME}' session = HTMLSession() def add_to_airtable(produkt_air="", retailer_air="", preis_air=""): headers = { "Authorization": f"Bearer {AIRTABLE_API_KEY}", "Content-Type": "application/json" } data = { "records": [ { "fields": { "Produkt": produkt_air, "Retailer": retailer_air, "Preis": preis_air } } ] } # 改用HTMLSession的post方法,变量名修改避免冲突 airtable_resp = session.post(endpoint, json=data, headers=headers) print(airtable_resp.status_code) return airtable_resp.status_code == 200 with open('urls.txt', 'r') as urls: for url in urls: # 处理url换行符,变量名修改避免冲突 scrape_resp = session.get(url.strip()) # 渲染JS加载动态内容,首次运行会自动下载chromium scrape_resp.html.render() produktscan = scrape_resp.html.find('title') produkt = produktscan[0].text produkt = produkt.replace(' | Google Shopping', '') for article in scrape_resp.html.find('tr.sh-osd__offer-row'): retailer = article.find('div.kPMwsc', first=True).full_text retailer = retailer.replace('Wird in einem neuen Fenster geöffnet', '') preis = article.find('div.drzWO', first=True).text add_to_airtable(produkt_air=produkt, retailer_air=retailer, preis_air=preis) print(produkt) print(retailer) print(preis) # 每个url处理完休眠1秒 time.sleep(1)
内容的提问来源于stack exchange,提问作者Kattamaran
相关产品推荐
相关产品推荐

