【问题标题】:Get links form wikipedia从维基百科获取链接
【发布时间】:2016-01-18 02:19:43
【问题描述】:

我正在使用scrapy来抓取这个页面:

https://en.wikipedia.org/wiki/List_of_shopping_malls_in_the_United_States

链接在:

data = response.xpath('//*[@id="mw-content-text"]/ul[9]/li').extract()

数据在哪里:

[<Selector xpath='//*/li' data=u'<li><a href="/wiki/Ala_Moana_Center" tit'>,
<Selector xpath='//*/li' data=u'<li><a href="/wiki/Kahala_Mall" title="K'>,
<Selector xpath='//*/li' data=u'<li><a href="/wiki/Pearlridge" title="Pe'>,
<Selector xpath='//*/li' data=u'<li><a href="/wiki/Prince_Kuhio_Plaza" t'>,
<Selector xpath='//*/li' data=u'<li><a href="/wiki/Victoria_Ward_Centers'>]

我需要的链接是:

https://en.wikipedia.org + href

例如:

'https://en.wikipedia.org'+'/wiki/Ala_Moana_Center'

为此,我正在使用正则表达式

link = 'https://en.wikipedia.org' + re.findall('href="([^"]+)',str(data[0]))[0]

name = re.findall('href="([^"]+)',str(data[0]))[0].replace('/wiki/','').replace('_',' ')

问题在于,使用这种方法我必须创建一个循环来获取链接,有一种方法可以直接从 scrapy 或至少以更有效的方式创建这些链接?

【问题讨论】:

    标签: python regex scrapy


    【解决方案1】:

    Nono,不需要正则表达式,将您的 XPath 直接指向 href 属性:

    data = response.xpath('//*[@id="mw-content-text"]/ul[9]/li/a/@href').extract()
    

    然后,使用urlparse.urljoin() 构造以response.url 为基础的绝对URL:

    from urlparse import urljoin
    
    base_url = response.url
    data = [urljoin(base_url, link) 
            for link in response.xpath('//*[@id="mw-content-text"]/ul[9]/li/a/@href').extract()]
    

    作为旁注,我并不特别喜欢 XPath 表达式中的 ul[9] 部分——一般来说,使用索引并不可靠并且很容易破坏——而且你无法阅读和理解表达式。看起来,您正在寻找夏威夷购物中心。根据前面的Hawaii标签定位链接:

    //a[. = "Hawaii"]/following::ul/li/a/@href 
    

    使用这个表达式,很容易看出你实际在定位什么。


    以下是如何按状态对链接进行分组,例如来自 Shell:

    $ scrapy shell https://en.wikipedia.org/wiki/List_of_shopping_malls_in_the_United_States
    >>> from urlparse import urljoin
    >>> from pprint import pprint
    >>>
    >>> base_url = response.url
    >>>
    >>> data = {}
    >>> for state in response.xpath("//h3[span[@class='mw-headline']]"):
    ...     state_name = state.xpath(".//a[@title]/text()").extract_first()
    ...     links = [urljoin(base_url, link) for link in state.xpath('./following-sibling::*[1]//li/a/@href').extract()]
    ...     data[state_name] = links
    >>>
    >>> pprint(data)
    

    【讨论】:

    • 谢谢,事实上我需要所有的链接。我更喜欢按州提供链接,因为我没有找到将链接与州相关联的模式,而无需事先知道页面中的州名。所以我会尝试: response.xpath('//*[@id="mw-content-text"]/ul/li').extract()
    • @LuisRamonRamirezRodriguez 当然,让我帮你按州对链接进行分组,请稍等。
    • @LuisRamonRamirezRodriguez 好的,更新了一个示例,试一试,请测试它是否可以处理没有状态链接的情况。谢谢。
    • 谢谢,太好了:如果商城没有链接,它会返回一个空列表。就像在德克萨斯州一样。在页面中有这些案例的链接,它有一整页针对该州的商场en.wikipedia.org/wiki/List_of_shopping_malls_in_Texas 但已经很好了,我在字典中的这些链接可能会令人困惑。
    猜你喜欢
    • 1970-01-01
    • 2020-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多