使用Scrapy爬虫读取网页时,如果目标数据是需要登录才能查看的页面,就需要处理cookies信息。很多人因此安装了其他更多的工具来处理cookies,其实仅凭Scrapy本身就可以完美实现爬取需要登录才能查看的页面了。
首先修settings.py文件,这是使用scrapy创建项目自动生成的文件:(取消相关行注释并修改:忽视robots文件,爬取延时0.3秒避免过大并发,开启cookies组件)
ROBOTSTXT_OBEY = False DOWNLOAD_DELAY = 0.3 COOKIES_ENABLED = True
然后只需要修改spiders文件夹下爬虫.py文件,首先我给出一般爬虫文件的格式,并且添加了一定的注释:
import scrapy
class Url(scrapy.Spider):
name = "pachong"
start_urls = [ #这种方式无需定义start_requests方法
"http://gyqyy.com" #输入目标网址列表
]
#下面根据不同目标定义不同的任务
def parse(self, response):
title = response.css("h1 *::text").extract_first()
body = response.css("body *::text").extract()
body = body.encode() #完成对爬取内容的定义和处理
filename = '%s.txt' % title #文件名
path = response.url #这里我保存了一下链接地址
with open(filename, 'wb') as f:
f.write(body) #写入文件
self.log('成功保存文件: %s' % filename)
要添加cookies,我使用了chrome浏览器下一个方便的cookies管理器插件:EditThisCookie,获取cookies信息也有很多方式,这里就不一一介绍了。之后可直接在Url类下添加cookies的键值信息:
cookies = { "login_token" : "a", "id" : "b", "class" : "c" }
修改完成后,爬虫程序代码如下:
#方案一,直接添加cookies键值
import scrapy
class Url(scrapy.Spider):
name = "pachong"
start_urls = [ #这种方式无需定义start_requests方法
"http://gyqyy.com" #输入目标网址列表
]
#添加cookies信息,修改相应键值
cookies = {
"login_token" : "a",
"id" : "b",
"class" : "c"
}
#下面根据不同目标定义不同的任务
def parse(self, response):
title = response.css("h1 *::text").extract_first()
body = response.css("body *::text").extract()
body = body.encode() #完成对爬取内容的定义和处理
filename = '%s.txt' % title #文件名
path = response.url #这里我保存了一下链接地址
with open(filename, 'wb') as f:
f.write(body) #写入文件
self.log('成功保存文件: %s' % filename)
修改完成后,即可正常爬取原先需要登录才可以浏览的页面数据了。
scrapy crawl Url
另外,还有两种方式可以模拟登录爬取,这里也一并介绍:
#方案二,提供post数据
import scrapy
class Url(scrapy.Spider):
name = "pachong"
allowed_domains = ["gyqyy.com"]
#下面开始登录
def start_requests(self):
url = 'http://www.gyqyy.com/'
# FormRequest 是Scrapy发送POST请求的方法
yield scrapy.FormRequest(
url = url,
#下面根据页面输入相关信息
formdata = {"username" : "user", "password" : "pass"},
callback = self.parse_page)
#下面根据不同目标定义不同的任务
def parse_page(self, response):
with open("test.html", "w") as filename:
filename.write(response.body)
#方案三,首先发送登录页面的get请求,获取到页面里的登录必须的参数,然后和账户密码一起post到服务器
import scrapy
class Url(scrapy.Spider):
name = "pachong"
start_urls = [ #这种方式无需定义start_requests方法
"http://gyqyy.com/login" #输入需要登录的目标网址
]
# 处理start_urls里的登录url的响应内容,提取登陆需要的参数(如果需要的话)
def parse(self, response):
# 提取登陆需要的参数
#_cs = response.xpath("//_cs").extract()[0]
# 发送请求参数,并调用指定回调函数处理
yield scrapy.FormRequest.from_response(
response,
formdata = {"username" : "user", "password" : "pass"},#, "_cs" = _cs},
callback = self.parse_page
)
# 获取登录成功状态,访问需要登录后才能访问的页面
def parse_page(self, response):
url = "http://www.gyqyy.com/blog"
yield scrapy.Request(url, callback = self.parse_newpage)
# 处理响应内容
def parse_newpage(self, response):
with open("test.html", "w") as filename:
filename.write(response.body)