问题
访问"https://www.pudong.gov.cn/zwgk/xqjy-jyjzdgz/2023/104/309147.html",其中请求头也带上足够字段,但是还是访问还是报错412
状态码412含义为:Precondition Failed,服务器在验证在请求的头字段中给出先决条件时,没能满足其中的一个或多个。这个状态码允许客户端在获取资源时在请求的元信息(请求头字段数据)中设置先决条件,以此避免该请求方法被应用到其希望的内容以外的资源上。
这一般是zf网站防止爬虫做的限制,设置cookies,并且过期时间很短
下面就是访问网页的需要cookies。浏览器内部主动获取cookies,然后在请求带上,而我们爬虫使用request没法直接获取cookies
解决
1.使用模拟浏览器
selenium,playwright等模拟浏览器访问。这部分没确认,而且考虑模拟浏览器比较慢
2.request请求需要获取cookies
本质需要在请求头中带上cookies,但是分析相关请求,但是分析下没有找到获取cookies,底层中肯定是存在获取cookies方式,但是比较耗时
针对两种方式折中下
通过模拟浏览器方式获取cookies,保存缓存,然后在通过requests模块去请求。等cookies过期再次通过模拟获取cookies.这里使用playwright模拟获取cookies
self.headers = {
'content-type': 'application/json',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36'
}
# 模拟浏览器方式获取cookies
def getCookies(url):
with sync_playwright() as p:
# 显示浏览器,每步操作等待100毫秒
browser = p.firefox.launch(headless=True, slow_mo=100)
context = browser.new_context()
# context.add_init_script(js)
page = context.new_page()
page.goto(url, timeout=5000) # 设置超时时间为5s
cookies = context.cookies()
browser.close()
runCookies = ""
for data in cookies:
runCookies += data['name'] + "=" + data['value'] + "; "
return runCookies
# 获取cookies
def _setCookies(self):
url = 'https://www.pudong.gov.cn/zwgk/zwgk_zfxxgkml_abmdr14_zfbm_jyj/index.html'
cookies = getCookies(url)
header = self.header
header["Cookie"] = cookies
# 获取页面
def getPageInfo(self, url):
try:
if self.getCrawler.getHeader().get("Cookie", "") == "":
self._setCookies()
with requests.session() as req:
response = req.get(url, headers=self.headers)
self._handle(response, url)
return response.text
print(page)
except Response412Error:
# 针对返回码412,重新获取cookies
try:
self._setCookies()
page = self.getCrawler.getBySession(url)
return getDataPuDongGov(url, page, model=self.model, logger=self.logger)
except Exception:
print("再次执行报错:" + url)
except Exception:
print("报错:" + url)