初识scrapy框架(四)------ POST登录

  前面的文章都是直接yield一个get请求,如果我们需要传入参数以post方法请求怎么办呢?下面我们以豆瓣

为例,先登录豆瓣网,再爬个人主页下推送的文章用户名,如果有跟多的需求可以再分析并书写相应的函数。

爬虫文件:

 1 import scrapy
 2 from douban.items import DoubanItem
 3 
 4 
 5 class UsrMgSpider(scrapy.Spider):
 6     name = 'usr_mg'
 7     allowed_domains = ['www.douban.com']
 8     start_url = 'https://accounts.douban.com/login'
 9     base_url = 'https://www.douban.com/'
10     data = {
11         'source': 'None',
12         'redir:https': '//www.douban.com/',
13         'form_email': '***********‘,
14         'form_password': '**************************',
15         'login': '登录',
16     }
17     headers = {
18         'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
19         'Accept-Encoding': 'gzip, deflate, br',
20         'Accept-Language': 'zh-CN,zh;q=0.9',
21         'Cache-Control': 'max-age=0',
22         'Connection': 'keep-alive',
23         'Host': 'www.douban.com',
24         'Upgrade-Insecure-Requests': 1,
25         'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.170 Safari/537.36',
26     }
27     # i = 1
28 
29     def start_requests(self):
30         print('00000000000000000000000000000')
31         yield scrapy.FormRequest(url=self.start_url, formdata=self.data, headers=self.headers, callback=self.parse_login)
32 
33     def parse_login(self, response):
34         print('=========================\n', response)
35         node_list = response.xpath('//*[@id="statuses"]/div[2]/div')
36         print(node_list)
37         if node_list == []:
38             return
39         next_page = response.xpath('//span[@class="next"]/a/@href').extract_first()
40         print(next_page)
41         for node in node_list:
42             item = DoubanItem()
43             item['usr_name'] = node.xpath('./div/div/div[1]/div[2]/a/text()').extract_first()
44             item['usr_link'] = node.xpath('./div/div/div[1]/div[2]/a/@href').extract_first()
45             yield item
46         # self.i += 1      # str(self.i)
47         next_url = self.base_url+next_page
48         yield scrapy.Request(url=next_url, callback=self.parse_login)

  通过重写start_requests函数,我们可以将第一次请求设置为POST请求。这里是用的 scrapy.FormRequest 实现

的,如果登录请求要传验证码,可以在加一步验证码的识别,但是第一次请求应该是请求登录页面,获取验证码,这

里如果不加验证码的处理,多次执行程序会导致网站出现验证码的反爬措施。所以好的程序应该是默认有验证码的处

理,具体而言就是先请求登录页,如果有验证码就识别,没有就不识别,然后再登录。

  这里的parse_login函数里实现了爬虫要求的推送文章的用户名,同事yield一个请求去爬取下一页的数据,有时候

自己写代码可能发现自己的代码运行到某一页就停了,但是网站并没有封你,后面的网页还可以访问。出现这种问题

可能是由于xpath有问题,因为xpath路径可能网页之间不一样,所以书写路径就要小心了。豆瓣这个网站我在爬的时

候发现11页与12页的xpath是不一样的,之前的xpath路径是直接复制的,后来在页面上自己写的,调试可用。

 

终端部分结果:

  爬到第101页时程序停止,因为网页第101页没有数据。

参数介绍:

  url: 就是需要请求,并进行下一步处理的url

  callback: 指定该请求返回的Response,由那个函数来处理。

  method: 请求一般不需要指定,默认GET方法,可设置为"GET", "POST", "PUT"等,且保证字符串大写

  headers: 请求时,包含的头文件。一般不需要

  meta: 比较常用,在不同的请求之间传递数据使用的。字典dict型

  encoding: 使用默认的 'utf-8' 就行。

  dont_filter: 表明该请求不由调度器过滤。这是当你想使用多次执行相同的请求,忽略重复的过滤器。默认为False。

 

posted @ 2018-05-16 15:05  巴蜀秀才  阅读(353)  评论(0编辑  收藏  举报