你的爬虫又被封了_你真是蠢的可以!用这个不再担心被封爬虫!

Spider

当 start_urls 未被指定,会调用 start_requests() ,该方法可以用于在爬取数据之前,先进行模拟登陆。

import scrapy from scrapy.http import Request from scrapy.selector import Selector from urllib.parse import urljoin from doubanTop250.items import Doubantop250Item class DoubanTop250Spider(scrapy.spiders.Spider): # 此处为上面留下的小坑 name = "douban" # 设置允许爬取的域名 allowed_domains = ["douban.com"] # header信息 my_header = { Host: www.douban.com, Referer: } # 表单需要提交的数据 form_data = {user: zone, pass: zone7} # 自定义信息,向下层响应(response)传递下去 customer_data = {key1: value1, key2: value2} def start_requests(self): return [scrapy.FormRequest("", formdata=self.form_data, # 表单提交的数据 headers=self.my_header, method=POST, # GET or POST meta=self.customer_data, # 自定义,向response传递数据 errback=self.error_handle, callback=self.logged_in, # 如果需要多次提交表单,且url一样,那么就必须加此参数 dont_filter,防止被当成重复网页过滤掉了 dont_filter=True )] def logged_in(self, response): # 解析模拟登陆数据 pass def parse(self, response): # 默认回调函数 pass def close(self,reson): # 关闭时调用 pass

scrapy.FormRequest 部分参数解析

私信菜鸟007获取源码啊!

Middleware

这里说一下,关于自定义 middleware 需要重写的几个方法,可能你看完这一段长篇大论之后,还是懵逼的,没关系,我也是这样。不过,当你继续往下看,看一个实例之后,你就会明白。

process_request(request, spider)

当每个request通过下载中间件时,该方法被调用。

process_request() 必须返回其中之一: 返回 None 、返回一个 Response 对象、返回一个 Request 对象或 raise IgnoreRequest 。

如果其返回 None ,Scrapy将继续处理该request,执行其他的中间件的相应方法,直到合适的下载器处理函数(download handler)被调用, 该request被执行(其response被下载)。如果其返回 Response 对象,Scrapy将不会调用 任何 其他的 process_request() 或 process_exception() 方法,或相应地下载函数; 其将返回该 response。 已安装的中间件的 process_response() 方法则会在每个 response 返回时被调用。如果其返回 Request 对象,Scrapy则停止调用 process_request方法并重新调度返回的 request。当新返回的 request 被执行后, 相应地中间件链将会根据下载的 response 被调用。

如果其返回一个 Response (可以与传入的response相同,也可以是全新的对象), 该response会被在链中的其他中间件的 process_response() 方法处理。如果其返回一个 Request 对象,则中间件链停止, 返回的request会被重新调度下载。处理类似于 process_request() 返回request所做的那样。如果其抛出一个 IgnoreRequest 异常,则调用 request 的 errback( Request.errback)。 如果没有代码处理抛出的异常,则该异常被忽略且不记录(不同于其他异常那样)。

参数:

request (Request 对象) – response 所对应的 requestresponse (Response 对象) – 被处理的 responsespider (Spider 对象) – response 所对应的 spider

process_exception(request, exception, spider)

当下载处理器(download handler)或 process_request() (下载中间件)抛出异常(包括IgnoreRequest异常)时,Scrapy调用 process_exception() 。

process_exception() 应该返回以下之一: 返回 None 、 一个 Response 对象、或者一个 Request 对象。

如果其返回 None ,Scrapy将会继续处理该异常,接着调用已安装的其他中间件的 process_exception() 方法,直到所有中间件都被调用完毕,则调用默认的异常处理。如果其返回一个 Response 对象,则已安装的中间件链的 process_response() 方法被调用。Scrapy将不会调用任何其他中间件的 process_exception() 方法。如果其返回一个 Request 对象, 则返回的request将会被重新调用下载。这将停止中间件的 process_exception() 方法执行,就如返回一个response的那样。

参数:

request (是 Request 对象) – 产生异常的requestexception (Exception 对象) – 抛出的异常spider (Spider 对象) – request对应的spider

UserAgentMiddleware

多数情况下,网站都会通过 user-agent 来识别访问的用户是否为一台机器,就像爬取豆瓣一样,如果你没有设置 user-agent 的话,就会被拒绝访问。因此,我们只使用一个 user-agent 显然是不够的,因此,我们要想个办法来设置随机的 user-agent。于是,我们便可以自定义 UserAgentMiddleware 来解决这个问题。

首先,在 setting.py 中添加 user-agent ,如下:

MY_USER_AGENT = [ MSIE (MSIE 6.0; X11; Linux; i686) Opera 7.23, iTunes/9.0.3 (Macintosh; U; Intel Mac OS X 10_6_2; en-ca), Opera/9.20 (Macintosh; Intel Mac OS X; U; en), Opera/9.0 (Macintosh; PPC Mac OS X; U; en), Mozilla/4.76 [en_jp] (X11; U; SunOS 5.8 sun4u), Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6, Mozilla/5.0 (X11; Linux i686; U;) Gecko/ Kazehakase/0.4.5, Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.71 Safari/537.1 LBBROWSER, Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727), Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11, Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11, Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Download 732; .NET4.0C; .NET4.0E), Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11, Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SV1; Download 732; .NET4.0C; .NET4.0E; 360SE), Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30), Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20, Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6, Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/ Ubuntu/10.10 (maverick) Firefox/3.6.10, Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.71 Safari/537.1 LBBROWSER, Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1, Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506), Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.12) Gecko/ Ubuntu/dapper-security Firefox/1.5.0.12, Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Download 732; .NET4.0C; .NET4.0E; LBBROWSER), Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1, Mozilla/4.8 [en] (X11; U; SunOS; 5.7 sun4u) ]

然后在 middlewares.py 中添加如下代码:

class MyUserAgentMiddleware(UserAgentMiddleware): def __init__(self, user_agent): self.user_agent = user_agent @classmethod def from_crawler(cls, crawler): return cls( user_agent=crawler.settings.get(MY_USER_AGENT) ) def process_request(self, request, spider): agent = random.choice(self.user_agent) request.headers[User-Agent] = agent

最后启用这个 middleware ,在 setting.py 中修改 MyUserAgentMiddleware 的优先级,如下:

DOWNLOADER_MIDDLEWARES = { # 首先禁止其原有的 UserAgentMiddleware scrapy.downloadermiddleware.useragent.UserAgentMiddleware: None, doubanTop250.middlewares.MyUserAgentMiddleware: 300, doubanTop250.middlewares.ProxyMiddleware: 543, }

ProxyMiddleware

除了要更改 user-agent 之外,我们还要使用 ip 代理来健壮我们的爬虫程序。那么,在 scrapy 中如何来设置我们的 ip 代理呢?

首先,在 setting.py 中添加如下代码,为代理 ip:

PROXIES = [ "194.186.20.62:21231" , "66.153.222.162:54684" , "219.234.5.128:3128" , "117.114.149.66:53281" , "117.114.149.66:53281" ]

ip 来自西刺代理,不过好像好多没用的代理。

然后在 middlewares.py 中添加如下代码:

from scrapy import signals import random class ProxyMiddleware(object): def __init__(self, ip): self.ip = ip @classmethod def from_crawler(cls, crawler): return cls(ip=crawler.settings.get(PROXIES)) def process_request(self, request, spider): ip = random.choice(self.ip) request.meta[proxy] = ip

最后启用这个 middleware ,在 setting.py 中修改 ProxyMiddleware 的优先级,如下:

DOWNLOADER_MIDDLEWARES = { # 首先禁止其原有的 UserAgentMiddleware scrapy.downloadermiddleware.useragent.UserAgentMiddleware: None, doubanTop250.middlewares.MyUserAgentMiddleware: 300, doubanTop250.middlewares.ProxyMiddleware: 543, }

瞎比比

经过这些操作之后,你的代码等级就提升了一个高度了。说了那么多,我们好像还没有将我们抓取的数据保存下来,那么下一篇文章将会说说如何保存我们的数据。后台回复【007】获取源码。