scrapy第一次请求方式的重写
# -*- coding: utf-8 -*-
import scrapy
from ..items import MaoyanItem
class MaoyanSpider(scrapy.Spider):
name = 'maoyan3'
allowed_domains = ['maoyan.com']
#重写start_requests()方法,把所有URL地址都交给调度器
def start_requests(self):
# 把所有的URL地址统一扔给调度器入队列
for offset in range(0, 91, 10):
url = 'https://maoyan.com/board/4?offset={}'.format(offset)
# 交给调度器
yield scrapy.Request(
url=url,
callback=self.parse_html
)
def parse_html(self,response):
#基准的xpath
dd_list = response.xpath('//dl[@class="board-wrapper"]/dd')
#for循环依次遍历
for dd in dd_list:
#创建对象'
item = MaoyanItem()
# 电影名称
# 如果不添加extract_first(),会得到一堆列表里面的选择器,但是我们的目标是得到字符串
item["name"] = dd.xpath("./a/@title").extract_first().strip()
# 电影主演
item["star"] = dd.xpath(".//p[@class='star']/text()").extract_first().strip()
#上映时间
item["time"] = dd.xpath('.//p[@class="releasetime"]/text()').extract_first().strip()
#把爬取的数据交给管道文件pipeline处理
#生成器
yield item
当起始请求需要设置header,cookie,data时,则要对起始请求做处理,所以需要重写第一次请求处理函数start_request(self)
1 设置header与cookie
如果在settings.py文件中设置请求头,则所有的蜘蛛文件都使用该请求头,然而不同的蜘蛛文件需要不同的请求头,因此需要给每个蜘蛛文件的请求设置独立的请求头.
设置独立的header和cookie方法为在蜘蛛文件中重写第一次请求处理方法start_requests
例:
# 重写第一次请求处理函数,要返回Request对象
def start_requests(self):
start_url = '要请求的链接'
headers = {}
cookies = {}
yield scrapy.Request(url=start_url, headers=headers,callback=self.parse,cookies=cookies)
scrapy.Request函数还有一个meta参数,值为字典格式,作用是携带数据在指定的回调函数中使用,使用方法:response.meta['键']
2 携带data数据
同样重写start_requests方法,返回FormRequest对象,此时请求方式为post
例:
def start_requests(self):
login_url = '要请求的链接'
# 发送post请求
data = {}
yield scrapy.FormRequest(url=login_url,formdata=data,callback=self.after_login)
scrapy.FormRequest.from_response方法可以从响应中自动提取表单POST地址,例如处理登录,需要先返回登录页面,再填充表单,然后提交
# 自动提取表单post地址
yield scrapy.FormRequest.from_response(
response,
headers=self.header,
formdata=data,
callback=self.after_login,
)
3 设置代理与随机选择请求头
通过下载器中间件来设置请求.
免费代理:
1
request.meta['proxy'] = 'http://' + '代理IP'
收费代理:需要先将账号密码base64编码,再设置给request,然后设置request.meta['proxy']:
auth = base64.b64encode({'帐号':'密码'}) #base64需要导入
request.headers['Proxy-Authorization'] = 'Basic ' + auth
request.meta['proxy'] = 'http://' + '代理IP'
例:
#coding:utf8
from settings import USER_AGENS,PROXIES
import random
import base64
# 随机更换浏览器身份中间件
class RandomUserAgent(object):
def process_request(self,request,spider):
user_agent = random.choice(USER_AGENS)
request.headers.setdefault('User-Agent',user_agent)
# 随机更换代理ip
class RandomProxy(object):
def process_request(self,request , spider):
proxy = random.choice(PROXIES) # 随机选出一个代理
if proxy.get('auth') is None: # 免费代理
request.meta['proxy'] = 'http://' + proxy['host']
else : # 收费代理
auth = base64.b64encode(proxy['auth'])
request.headers['Proxy-Authorization'] = 'Basic ' + auth
request.meta['proxy'] = 'http://' + proxy['host']
4 在scrapy中使用selenium
如果有些页面实在难以爬取,可以使用selenium方式,但是此方式会慢,所以尽量去抓包解析页面结构爬取.
使用: 在下载器中间件中,截取request,使用selenium对request的url发送请求,将获取的response返回,不使用下载器发送请求.