多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## 1. 通常防止爬虫被反主要有以下几个策略: > 1. 置User-Agent(随机切换User-Agent,模拟不同用户的浏览器信息) > 2. ookies(也就是不启用cookies middleware,不向Server发送cookies,有些网站通过cookie的使用发现爬虫行为) > 3. 过COOKIES_ENABLED 控制 CookiesMiddleware 开启或关闭 > 4. 迟下载(防止访问过于频繁,设置为 2秒 或更高) > 5. gle Cache 和 Baidu Cache:如果可能的话,使用谷歌/百度等搜索引擎服务器页面缓存获取页面数据。 > 6. P地址池:VPN和代理IP,现在大部分网站都是根据IP来ban的。 > 7. Crawlera(专用于爬虫的代理组件),正确配置和设置下载中间件后,项目所有的request都是通过crawlera发出。 > ## 2. 爬虫遇到的问题 ### 2.1 scrapy抓取到的html和浏览器的不一致 用xpath在浏览器上可以卡取到数据,但是程序就不行,弄了半天发现浏览器调试下的HTML和scrapy抓取到的不一样 `print(response.text)`打印一下获取到的数据,和浏览器不一样,改xpath匹配规则 ### 2.2 获取多个标签的文字 tr标签及其子标签中的文字 ~~~ content = response.xpath("//div[@class='pcb']//div[@class='t_fsz']/table[1]//tr")[0].xpath('string(.)').extract()[0] ~~~ 例:获取table标签下的所有文字 ![](https://box.kancloud.cn/c10a5c1fba0b7a35f249bb4643059da6_1634x769.png) ~~~ info_table = response.xpath("//table[@class='specificationBox']") if len(info_table)>=1 : instructions = info_table[0].xpath('string(.)').extract()[0] ~~~ ### 2.3 cookie 有的网站,会把网页重定向,此时应该让我们的爬虫跟着重定向,做以下设置 ~~~ HTTPERROR_ALLOWED_CODES = [301] REDIRECT_ENABLED = True ~~~ ### 2.4 js渲染 ![](https://box.kancloud.cn/3a3ab484a9d919cefed75e6e91d3fddc_484x346.png) 如上面的商品价格,没有浏览器帮我们进行技术渲染,scrapy是得不到结果的,所以选择Selenium+PhantomJS(模拟无界面浏览器) 1. 自定义下载中间件,处理request ~~~ class PhantomJSMiddleware(object): def __init__(self,crawler ): self.webDriver = webdriver.PhantomJS() @classmethod def from_crawler(cls, crawler): return cls(crawler) def process_request(self, request, spider): if 'product' in request.url: self.webDriver.get(request.url) content = self.webDriver.page_source.encode('utf-8') print("===========使用selenium下载!!!!!!!!!") # 返回response,这样框架就不会去重复的下载了 return HtmlResponse(request.url, encoding='utf-8', body=content, request=request) ~~~ 2. 设置settings.py文件 把自定义的下载中间件加入 ~~~ DOWNLOADER_MIDDLEWARES = { 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None, 'scrapyredis.middlewares.RandomAgentMiddleWare': 543, 'scrapyredis.middlewares.PhantomJSMiddleware': 545, } ~~~ ### 2.5 使用selenium+PhantomJS(设置请求头) 其他组件设置的UserAgent,不会设置在PhantomJS发起的请求中,所以要单独设置请求头,否则就像下边这样爬虫被识别 ![](https://box.kancloud.cn/1f679ed88d5d7c613b1f61080c299544_1685x595.png) ~~~ class PhantomJSMiddleware(object): def __init__(self,crawler): self.ua = UserAgent() # 取到其定义的获取Useragent的方法 self.ua_type = crawler.settings.get("RANDOM_UA_TYPE", "random") self.fdfs = FDFSClient() crawler.spider.logger.info("=========PhantomJS浏览器初始化!!!") def getAgent(): userAgent = getattr(self.ua, self.ua_type) crawler.spider.logger.info("=====设置代理userAgent:{0}".format(userAgent)) return userAgent dcap = dict(DesiredCapabilities.PHANTOMJS) dcap["phantomjs.page.settings.userAgent"] = (getAgent()) self.webDriver = webdriver.PhantomJS(desired_capabilities=dcap) @classmethod def from_crawler(cls, crawler): return cls(crawler) def process_request(self, request, spider): # 详细处理页 if len(spider.detailList)>=1: for detail in spider.detailList: if detail in request.url: spider.logger.info("===========使用selenium下载") self.webDriver.get(request.url) content = self.webDriver.page_source.encode('utf-8') # spider.logger.info("===========保存快照") # screenshotData = self.webDriver.get_screenshot_as_png() # screenshotUri = self.fdfs.save(screenshotData) # request.meta['screenshot'] = screenshotUri return HtmlResponse(request.url, encoding='utf-8', body=content, request=request) def process_response(self, request, response, spider): # print(response.text) return response ~~~ 解决 ![](https://box.kancloud.cn/1b13f15960869e8051841059c5618e5d_1866x639.png)