scrapy分页抓取网页(【每日一题】scrapy发现爬虫还是登陆之前的状态)

优采云 发布时间: 2021-10-07 12:16

  scrapy分页抓取网页(【每日一题】scrapy发现爬虫还是登陆之前的状态)

  最近接触scrapy,爬了几个网站,用起来还是挺流畅的。

  前几天,一个业务同事让我帮他抓取网站上的一个用户信息,我答应了。毕竟,通过前面的几次爬行,我已经信心爆棚了(从此)入坑)。

   拿到一个网站之后就是先分析网站,分析之后发现需要的数据要登陆才能看到.这个可难不倒我,不就是模拟登陆吗,小菜一碟.

用chrome分析一下,看到有用户名,密码,还有其他两个校验值.另外还有一个重定向的callback值.如下:

  接下来,登录并观察post请求的状态。因为有上面这行代码,跳转太快了,没看到post请求,删掉上面那行代码,然后再请求,这次看到了表单发送信息。

  下一步就是编写代码并模拟登录。我马上写代码,然后开始测试。(还记得上面提到的两个校验值中的哪一个吗?这两个值都是动态的,可以使用正则的登陆页面提取出来)。

  部分代码如下:

  

name = "form"

download_delay = 0.18

allowed_domains = ["http://www.xxxxxx.com"]

headers = {

"Accept":"*/*",

"Accept-Encoding":"gzip, deflate, sdch",

"Accept-Language":"zh-CN,zh;q=0.8",

"Cache-Control":"max-age=0",

"Connection":"keep-alive",

"Host": "www.xxxxxx.com",

"User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36"

}

def start_requests(self):

return [scrapy.Request("http://www.xxxxxxx.com/user/login",meta={'cookiejar':1},headers=self.headers, callback=self.post_login)]

def post_login(self, response):

# 下面这句话用于抓取请求网页后返回网页中的_xsrf字段的文字, 用于成功提交表单

protected_code = Selector(response).xpath('//label[@class="rem"]/input[@name="protected_code"]/@value').extract()[0]

matchObj=re.search(r'\"csrftk\":\"(.*)\",\"img_path\"',response.text)

csrf_tk=matchObj.group(1)

logging.log(logging.WARNING, u"正则获取的值----"+csrf_tk)

# FormRequeset.from_response是Scrapy提供的一个函数, 用于post表单

# 登陆成功后, 会调用after_login回调函数

return [scrapy.FormRequest.from_response(response,method="POST",

headers=self.headers, # 注意此处的headers

formdata={

'protected_code': protected_code,

'email': 'xxxxxx@qq.com',

'csrf_tk': csrf_tk,

'password': 'xxxxxxxxxx',

'remember': 'true',

},

meta={'cookiejar': response.meta['cookiejar']},

callback=self.after_login,

dont_filter=True

)]

  然后设置 COOKIES_ENABLED = True 和 COOKIES_DEBUG=True 进行测试。结果不成功。查看日志发现cookie还是登录前的状态,登录端是302定向的。(现在想来,应该是scrapy重定向的时候,用cookie还是登录前的cookie,所以未来状态仍然在登录之前)。

  遇到这种情况,尝试关闭重定向,REDIRECT_ENABLED = False,然后测试一下,发现爬虫直接退出了。根据错误信息在网上找到答案,HTTPERROR_ALLOWED_CODES = 302,然后再次运行,完美解决。我得到了我想要的数据。到这个时候已经花了好几个小时了。中间走了很多弯路。

  总结:遇到错误时,应该仔细分析错误信息,多尝试。保持清晰和耐心。从技术上来说,你对scrapy的理解还不够,对cookies和redirect的理解还不到位。了解操作原理,解决问题。这要简单得多。

  REDIRECT_ENABLED = False 关闭重定向,不会重定向到新地址

  HTTPERROR_ALLOWED_CODES = [302,] 返回302时,视为正常返回,可以正常写cookies

  顺便说一句,python在解决实际问题的时候还是很实用的,可以快速上手,而且有很多开源库。建议大家有时间学习

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线