爬蚂蜂窝,然后遇到了 521response 反爬。自己搜了一下这个反爬还好处理,就是解码设置 cookie 的事。 但是我后来测试时候发现其实只要设置一个 5 秒左右的延时,通过 selenium 返回的 page_source 就是跳过反爬信息得到的完整页面信息了。
于是综上探索,我预想的是在 scrapy 中间件中加入 selenium,在 process_request 里做 get 请求之后,time.sleep 四五秒钟,然后返回 response 做后续处理。
想的是很美好,但是测试时候发现,因为中间件的 selenium 做 get 请求时,url 地址是 request.url,而这个 url 好像因为之前 scrapy 自带的 request 没有通过反爬然后就从一开始 url 就变成了 www.mafengwo.cn/robot.txt ,那这个 url 肯定是没法用了。用 spider.start_urls 的话又要处理一个列表问题,如果是爬好几个页面感觉从这个列表提取 url 也不是很靠谱啊。
那么有什么靠谱点的办法,让 request.url 传递过去正常的 url 呢?
附上 selenium 中间件的代码:
class SeleniumMiddleWares(object):
def __init__(self):
self.driver_path = '/Users/michealki/Downloads/chromedriver'
self.options = Options()
self.options.add_experimental_option('excludeSwitches', ['enable-automation'])
# self.options.add_argument('--headless')
self.driver = selenium.webdriver.Chrome(executable_path=self.driver_path,options=self.options)
@classmethod
def from_crawler(cls, crawler):
s = cls()
crawler.signals.connect(s.spider_closed, signal=signals.spider_closed)
return s
def process_request(self, request, spider):
#url = request.url
url = spider.start_urls[0]
self.driver.get(url)
time.sleep(5)
return HtmlResponse(url=self.driver.current_url, body=self.driver.page_source,
encoding="utf-8", request=request)
def spider_closed(self, spider):
self.driver.quit()
class Spider0(scrapy.Spider):
name = 'spider0'
start_urls = ['http://www.mafengwo.cn/poi/7918553.html']
def parse(self,response):
pass
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.