Python如何访问类作用域外的response变量以更新__VIEWSTATE等爬取参数
核心问题解答
首先直接给出结论:不可以。你代码里的response是Scraper类下bot方法的局部变量,仅在方法内部的运行周期内有效,类作用域外完全无法访问,你当前的写法运行时会直接抛出NameError: name 'response' is not defined的报错。
现有代码的其他问题
- 你在
bot方法中调用了self.event_state和self.event_validate,但没有将传入的参数赋值给实例属性,运行时会触发AttributeError - 分页逻辑里没有更新两个校验参数的步骤,ASP.NET站点的
__VIEWSTATE和__EVENTVALIDATION会随每次响应刷新,不更新的话第二页请求就会失效 - 初始请求没有先获取首页的默认校验参数,直接传入占位值请求大概率会被拦截
修正后实现方案
不需要把response拿到类外处理,直接在类内部的循环里完成参数提取和更新即可,修正代码如下:
import requests from scrapy.selector import Selector class Scraper: def __init__(self): self.cookies = {} self.headers = { # 建议补充UA头,避免被拦截 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36' } self.event_state = '' self.event_validate = '' self.url = 'https://registers.maryland.gov/RowNetWeb/Estates/frmEstateSearch2.aspx' def get_initial_params(self): """首次GET请求首页,获取初始的校验参数""" r = requests.get(url=self.url, headers=self.headers, cookies=self.cookies) response = Selector(text=r.text) self.event_state = response.xpath('//input[@name="__VIEWSTATE"]/@value').get() self.event_validate = response.xpath('//input[@name="__EVENTVALIDATION"]/@value').get() # 更新Cookie,后续请求保持会话一致 self.cookies.update(r.cookies.get_dict()) def bot(self): # 先拿初始参数 self.get_initial_params() counter = 0 while True: data = { '__EVENTTARGET': f'dgSearchResults$ctl24$ctl0{counter}', '__VIEWSTATE': self.event_state, '__VIEWSTATEGENERATOR': '11C1F95B', '__EVENTVALIDATION': self.event_validate, 'cboType': 'RE', 'DateOfFilingFrom': '01/01/2021', 'DateOfFilingTo': '10/20/2021', 'cboPartyType': 'Decedent', 'cmdSearch': 'Search' if counter == 0 else '' # 首次搜索带cmdSearch参数,分页的时候可以去掉避免重复触发搜索 } r = requests.post(url=self.url, headers=self.headers, cookies=self.cookies, data=data) # 更新会话Cookie self.cookies.update(r.cookies.get_dict()) response = Selector(text=r.text) links = response.xpath('//a[contains(@href, "RecordId")]') if not links: break for link in links: ids = link.xpath('.//@href').get() print(ids) # 提取新的校验参数,更新给下一次请求用 self.event_state = response.xpath('//input[@name="__VIEWSTATE"]/@value').get() self.event_validate = response.xpath('//input[@name="__EVENTVALIDATION"]/@value').get() counter += 1 if __name__ == '__main__': scraper = Scraper() scraper.bot()
修改说明
- 新增
__init__方法初始化实例属性,统一管理请求头、Cookie和校验参数 - 新增
get_initial_params方法,首次先GET首页获取初始校验参数和会话Cookie,保证第一次请求合法 - 每次POST请求拿到响应后,直接在循环内提取新的
__VIEWSTATE和__EVENTVALIDATION更新到实例属性,下一次分页请求直接使用最新值 - 统一维护会话Cookie,避免会话中断导致请求失效
内容的提问来源于stack exchange,提问作者Awais
相关产品推荐
相关产品推荐

