百度网页关键字抓取(学习Python,就避免不了爬虫,而Scrapy就是最简单的图片爬虫)
优采云 发布时间: 2021-09-10 23:12百度网页关键字抓取(学习Python,就避免不了爬虫,而Scrapy就是最简单的图片爬虫)
学习Python离不开爬虫,Scrapy是最受欢迎的。可以爬取文字信息(比如职位信息、网站评论等),也可以爬取图片,比如看到一些不错的网站展示了很多漂亮的图片(这里仅供个人学习Scrapy使用,不是用于商业用途),您可以下载它。好了,话不多说,下面开始一个简单的图片爬虫。
首先,我们需要一个浏览器来方便的查看html路径。建议使用火狐开发版() 这个版本的火狐标志是蓝色的
安装这个之后就不需要安装firebug、firepath等插件了
这里的例子,以花瓣网为例,抓取本页图片。
第一步:打开火狐浏览器,使用上面的网址访问,导航到Inspector选项卡,点击箭头然后选择一张图片,你就可以看到所选图片的位置(见下图)
这里我们发现打开的页面收录很多主题的图片,每个主题对应一个图片链接地址。打开后就是这个话题对应的图片。那么我们的目的就是抓取每个话题下的图片,所以第一步就是获取每个话题的链接,打开链接,查看图片地址,一一下载。现在我大概知道我们的例子有两层结构:①访问首页,展示不同主题的图片 ②打开每个主题,展示主题下方的图片
现在开始创建scrapy项目(可以参考前面的文章)
这里我创建了一个huaban2项目(我之前又做了一个,所以这里就命名为huaban2,随便我想),然后我创建了一个spider,begin是一个命令行文件,里面是scrapy Crawl meipic的命令,见稍后
第 2 步:实现蜘蛛
# -*- coding: utf-8 -*-
from huaban2.items import Huaban2Item
import scrapy
class HuabanSpider(scrapy.Spider):
name = 'meipic'
allowed_domains = ['meisupic.com']
baseURL = 'http://www.meisupic.com/topic.php'
start_urls = [baseURL]
def parse(self, response):
node_list = response.xpath("//div[@class='body glide']/ul")
if len(node_list) == 0:
return
for node in node_list:
sub_node_list = node.xpath("./li/dl/a/@href").extract()
if len(sub_node_list) == 0:
return
for url in sub_node_list:
new_url = self.baseURL[:-9] + url
yield scrapy.Request(new_url, callback=self.parse2)
def parse2(self, response):
node_list = response.xpath("//div[@id='searchCon2']/ul")
if len(node_list) == 0:
return
item = Huaban2Item()
item["image_url"] = node_list.xpath("./li/a/img/@data-original").extract()
yield item
解释一下这段代码:使用scrapy genspider meipic生成蜘蛛后,已经写好了默认结构,这里我们设置了一个baseURL,默认方法是parse。从上面的分析我们知道需要获取每个topic的链接,所以我们使用xpath来定位
node_list = response.xpath("//div[@class='body glide']/ul")
这样我们就得到了一个selector对象,赋值给变量node_list,加一个if判断,如果没了就结束(return后的代码不会被执行,这个大家应该都知道),然后我们要取/ul/下li/dl下的href,用extract()返回一个list,就是dl下的所有链接。接下来,我们需要拼接一个完整的 URL,然后请求这个 URL,并用 yield 返回。因为我们真正要抓取的图片在页面的第二层,所以这里的回调函数调用了一个parse2(这是我自己定义的一个方法),parse2是用来处理图片链接的。同理,从之前拼接的URL请求页面返回parse2的响应
这里我们要获取图片的地址,就是//div[@id='SearchCon2']/ul/li/a/img/@data-original,获取到地址后,交给item (我们定义了item字段用来存放图片的地址),这样item返回到管道中
items.py
import scrapy
class Huaban2Item(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
image_url = scrapy.Field()
image_paths = scrapy.Field()
管道.py
from scrapy.pipelines.images import ImagesPipeline
from scrapy.exceptions import DropItem
import scrapy
class Huaban2Pipeline(ImagesPipeline):
def get_media_requests(self, item, info):
for image_url in item['image_url']:
yield scrapy.Request(image_url)
def item_completed(self, results, item, info):
image_paths = [x["path"] for ok, x in results if ok]
if not image_paths:
raise DropItem("Item contains no image")
item['image_paths'] = image_paths
return item
因为要下载图片,所以需要在settings.py中配置一个路径,同时
需要的配置如下,其他默认即可
MEDIA_ALLOW_REDIRECTS = True #因为图片地址会被重定向,所以这个属性要为True
IMAGES_STORE = "E:\\img" #存储图片的路径
ROBOTSTXT_OBEY = False #Robot协议属性要为False,不然就不会抓取任何内容
ITEM_PIPELINES = {
'huaban2.pipelines.Huaban2Pipeline': 1,
} #pipeline要enable,不然不会出来pipeline的请求
最后我们写了一个begin.py文件来执行
from scrapy import cmdline
cmdline.execute('scrapy crawl meipic'.split())
多说一点,可以存储不同大小的图片,如果需要,可以在settings.py中添加属性
IMAGES_THUMBS = {'small': (100, 100), 'big': (800, 1000)}
好了,基础写完了,可以开始执行了。