python - 使用scrapy,python中的站点地图蜘蛛解析站点地图中具有不同url格式的url

标签 python web-scraping sitemap scrapy

我在 scrapy、python 中使用站点地图蜘蛛。 站点地图似乎有不寻常的格式,网址前面有“//”:

<url>
    <loc>//www.example.com/10/20-baby-names</loc>
</url>
<url>
    <loc>//www.example.com/elizabeth/christmas</loc>
 </url>

myspider.py

from scrapy.contrib.spiders import SitemapSpider
from myspider.items import *

class MySpider(SitemapSpider):
    name = "myspider"
    sitemap_urls = ["http://www.example.com/robots.txt"]

    def parse(self, response):
        item = PostItem()           
        item['url'] = response.url
        item['title'] = response.xpath('//title/text()').extract()

        return item

我收到这个错误:

raise ValueError('Missing scheme in request url: %s' % self._url)
    exceptions.ValueError: Missing scheme in request url: //www.example.com/10/20-baby-names

如何使用站点地图蜘蛛手动解析 url?

最佳答案

如果我没看错,您可以(为了快速解决)覆盖 SitemapSpider_parse_sitemap 的默认实现。这不是很好,因为您将不得不复制大量代码,但应该可以工作。 您必须添加一种方法来生成带有方案的 URL。

"""if the URL starts with // take the current website scheme and make an absolute
URL with the same scheme"""
def _fix_url_bug(url, current_url):
    if url.startswith('//'):
           ':'.join((urlparse.urlsplit(current_url).scheme, url))
       else:
           yield url

def _parse_sitemap(self, response):
    if response.url.endswith('/robots.txt'):
        for url in sitemap_urls_from_robots(response.body)
            yield Request(url, callback=self._parse_sitemap)
    else:
        body = self._get_sitemap_body(response)
        if body is None:
            log.msg(format="Ignoring invalid sitemap: %(response)s",
                    level=log.WARNING, spider=self, response=response)
            return

        s = Sitemap(body)
        if s.type == 'sitemapindex':
            for loc in iterloc(s):
                # added it before follow-test, to allow test to return true
                # if it includes the scheme (yet do not know if this is the better solution)
                loc = _fix_url_bug(loc, response.url)
                if any(x.search(loc) for x in self._follow):
                    yield Request(loc, callback=self._parse_sitemap)
        elif s.type == 'urlset':
            for loc in iterloc(s):
                loc = _fix_url_bug(loc, response.url) # same here
                for r, c in self._cbs:
                    if r.search(loc):
                        yield Request(loc, callback=c)
                        break

这只是一个大概的想法,未经测试。所以它要么完全不起作用,要么可能存在语法错误。请通过评论回复,以便我改进我的回答。

您尝试解析的站点地图似乎有误。来自 RFC 的缺失方案 is perfectly fine ,但站点地图 require URLs to begin with a scheme .

关于python - 使用scrapy,python中的站点地图蜘蛛解析站点地图中具有不同url格式的url,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27286927/

相关文章:

python - 具有多个 iPyWidgets 下拉菜单的交互式 Covid 绘图

python-3.x - 运行多个蜘蛛时 react 堆无法重新启动

javascript - DOM 准备好后立即开始抓取 Nightmarejs

seo - 我可以更改 Google 站点提交中的站点地图名称吗?

c# - asp.net web 表单中站点地图权限中的用户权限

Django 站点地图索引示例

python - 网页抓取 - 使用 BeautifulSoup 和 Python 从类(class)中获取文本?

python - Tkinter 消息框在关闭后重新出现

python - web2py 和数据库事务

java - xPath 适用于最后一页,但不适用于第一页 - Selenium Java