python - 如何让 Python Scrapy 从网页中提取所有外部链接的所有域?
问题描述
我希望循环检查每个链接 - 如果它去外部域输出它 - 目前它输出所有链接(内部和外部)。我搞砸了什么?(为了测试,我调整了代码,只在一个页面上工作,而不是爬取网站的其余部分。)
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
import re
class MySpider(CrawlSpider):
name = 'crawlspider'
allowed_domains = ['en.wikipedia.org']
start_urls = ['https://en.wikipedia.org/wiki/BBC_News']
rules = (
Rule(LinkExtractor(), callback='parse_item', follow=False),
)
def parse_item(self, response):
item = dict()
item['url'] = response.url
item['title']=response.xpath('//title').extract_first()
for link in LinkExtractor(allow=(),deny=self.allowed_domains).extract_links(response):
item['links']=response.xpath('//a/@href').extract()
return item
解决方案
您方法中的逻辑parse_item
看起来不太正确
def parse_item(self, response):
item = dict()
item['url'] = response.url
item['title']=response.xpath('//title').extract_first()
for link in LinkExtractor(allow=(),deny=self.allowed_domains).extract_links(response):
item['links']=response.xpath('//a/@href').extract()
return item
您正在从提取器中循环遍历每个link
内容,但始终设置item["links"]
为完全相同的内容(来自响应页面的所有链接)。我希望您尝试item["links"]
将所有链接设置为LinkExtractor
? 如果是这样,您应该将方法更改为
def parse_item(self, response):
item = dict()
item['url'] = response.url
item['title'] = response.xpath('//title').extract_first()
links = [link.url for link in LinkExtractor(deny=self.allowed_domains).extract_links(response)]
item['links'] = links
return item
如果您真的只想要域,那么您可以使用urlparse
fromurllib.parse
来获取netloc
. 您可能还想用set
. 所以你的解析方法会变成(最好在文件顶部导入)
def parse_item(self, response):
from urllib.parse import urlparse
item = dict()
item["url"] = response.url
item["title"] = response.xpath("//title").extract_first()
item["links"] = {
urlparse(link.url).netloc
for link in LinkExtractor(deny=self.allowed_domains).extract_links(response)
}
return item
推荐阅读
- java - 将 java 7 迁移到 java 8 - forEach 中的 forEach 用于 HashMap 中的 HashMap?
- python-3.x - Python格式不完整日期为YYYYMM
- idl-programming-language - 如何通过 IDL 将超过 7 列写入 csv 文件?
- asp.net-mvc - 如何保护没有验证的旧网站?
- ruby - 配置文件,logstash ruby filter event.get("message").match() 错误
- python-3.x - 使用 pickle 加载 TfidfVectorizer 时解决 AttributeError
- python - virtualenv 在数字海洋的 ubuntu 18.04 服务器上失败
- sql - 如何使用链接服务器中的存储过程将 int 传递给 OPEN QUERY?
- angular - 如何在不同目录中使用 Angular CLI
- google-fonts - font-family Work Sans 在 Google Chrome 中不起作用