简介
之前写了一篇爬妹子图的文章《Python 3 实战Scrapy爬取妹子图》,但是有点粗糙,几乎都是无差别抓取页面所有图片和链接然后过滤,这篇文章优化了代码,让我们的爬虫更高效,爬取的图片质量更高,这里我选了一个妹子图非常多、质量非常高、又很正经的壁纸网站来实验,这里是爬取页面入口->,点击查看!
1.一级页面分析
打开F12分析了这个页面,你会发现这个页面很简单,分页都给你写清楚了多少页,主体页面是一个div+css结构,列表用了ul+li标签:
Screenshot from 2017-07-12 22-08-13.png
用一句xpath表达式就能获取到li标签里面所有的a链接地址,高效而且无多余的链接
# 一级页面的处理函数
def parse(self, response):
# 提取界面所有的符合入口条件的url
all_urls = response.xpath('//div[@class="main"]/ul/li/a/@href').extract()
# 遍历获得的url,继续爬取
for url in all_urls:
# urljoin生成完整url地址
url = urljoin(response.url, url)
yield Request(url, callback=self.parse_img)
2.二级页面分析
当我们点击一个美女图片之后会进去一个二级页面,这个页面的才是这个美女的所有图片合集,这个页面比较简单:
Screenshot from 2017-07-12 22-16-35.png
# 二级页面的处理函数
def parse_img(self, response):
item = PicscrapyItem()
# 提前页面符合条件的图片地址
item['image_urls'] = response.xpath('//img[@id="bigImg"]/@src').extract()
yield item
# 提取界面所有复合条件的url
all_urls = response.xpath('//ul[@id="showImg"]/li/a/@href').extract()
# 遍历获得的url,继续爬取
for url in all_urls:
url = urljoin(response.url, url)
yield Request(url, callback=self.parse_img)
通过parse和parse_img这两个函数的递归调用就可以获取所有符合条件的图片,基本上不会访问多余的链接,下载多余的图片...
另外下载图片的时候做了一些优化,之前图片名称是随机生成,现在改成取url一部分加随机数,这样同一个妹子的图片就可以放到一起了,不会乱七八糟了,方法是重写父类函数
# 重写函数,修改了下载图片名称的生成规则,改成了url地址的最后一个加了随机送
def file_path(self, request, response=None, info=None):
if not isinstance(request, Request):
url = request
else:
url = request.url
url = urlparse(url)
img_name = url.path.split('/')[5].split('.')[0] + '-' + str(random.randint(1000, 9999))
return '%s.jpg' % img_name
总结
经过优化后,100M宽带轻轻松松跑满,目测这个页面应该有上万张图片,童鞋,你的硬盘吃的消吗?
Github地址如下:点击获取代码
网友评论