问题:如何使用 Scrapy 从 img src
标签下的相对路径创建非重复的绝对路径列表?
背景:我正在尝试使用Scrapy抓取网站,提取img src
标签下的所有链接,将相对路径转换为绝对路径,然后生成 CSV 或列表数据类型的绝对路径。我计划将上述功能与使用 Scrapy 实际下载文件并同时抓取链接相结合,但当我到达它时我会跨过那座桥。作为引用,以下是有关假设目标站点的一些其他详细信息:
- 相对路径类似于
img src="/images/file1.jpg"
,其中 images 是一个目录( www.example.com/products/images),无法直接抓取文件路径。 - 这些图像的相对路径不遵循任何逻辑命名约定(例如 file1.jpg、file2.jpg、file3.jpg)。
- 不同文件的图像类型有所不同,其中最常见的是 PNG 和 JPG。
遇到的问题:即使在彻底阅读了 Scrapy 文档并浏览了大量过时的 Stackoverflow 问题之后 [例如 this question] ],我似乎无法得到我想要的精确输出。我可以拉出相对路径并重建它们,但输出关闭。以下是我在当前代码中注意到的问题:
在 CSV 输出中,既有填充行也有空白行。我最好的猜测是,每一行代表抓取特定页面的相对路径的结果,这意味着空白行是负面结果。
CSV 中的每个非空白行都包含一个以逗号分隔的 URL 列表,而我只想在一行中包含一个单独的、非重复的值。带有逗号分隔列表的行的数量似乎支持了我对幕后发生的事情的怀疑。
当前代码:我使用“scrapycrapy relpathfinder -o output.csv -t csv”在命令行中执行以下代码。
from scrapy.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors import LinkExtractor
from scrapy.item import Item, Field
class MyItem(Item):
url=Field()
class MySpider(CrawlSpider):
name='relpathfinder'
allowed_domains=['example.com']
start_urls=['https://www.example.com/']
rules = (Rule(LinkExtractor(allow=()), callback='url_join', follow=True),)
def url_join(self,response):
item=MyItem()
item['url']=[]
relative_url=response.xpath('//img/@src').extract()
for link in relative_url:
item['url'].append(response.urljoin(link))
yield item
谢谢!
最佳答案
我会使用项目管道来处理重复的项目。
# file: yourproject/pipelines.py
from scrapy.exceptions import DropItem
class DuplicatesPipeline(object):
def __init__(self):
self.url_seen = set()
def process_item(self, item, spider):
if item['url'] in self.url_seen:
raise DropItem("Duplicate item found: %s" % item)
else:
self.url_seen.add(item['url'])
return item
并将此管道添加到您的settings.py
# file: yourproject/settings.py
ITEM_PIPELINES = {
'your_project.pipelines.DuplicatesPipeline': 300,
}
然后你只需要运行你的蜘蛛scrapy scrap relpathfinder -o items.csv
,管道就会为你删除重复的项目。因此在 csv 输出中不会看到任何重复项。
关于python - Scrapy:从相对路径构造绝对路径的非重复列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48051158/