【问题标题】:Python scraper (Scraperwiki) only getting half of the tablePython 刮板(Scraperwiki)只拿到了一半的表
【发布时间】:2013-01-13 08:52:40
【问题描述】:

我正在 Scraperwiki 中学习如何使用 Python 编写爬虫。到目前为止一切都很好,但是我花了几天的时间来解决一个我无法解决的问题。我正在尝试从表中获取所有链接。它可以工作,但从 001 到 486 的链接列表中,它只会在 045 处开始抓取它们。网址/来源只是网站上的城市列表,来源可以在这里看到:
@987654321 @ 和具体的 html 从这里开始:

  </td></tr>
  <tr><td class=dt1><a href="by_city_001.html">'s-Gravenzande, South Holland Province&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;Aberystwyth, Ceredigion, Wales</a></td>
  <td class=dt1><a href="by_city_244.html">Los Corrales de Buelna,  Cantabria&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;Lousada, Porto District, Northern Portugal</a></td>
  </tr>
  <tr><td class=dt1><a href="by_city_002.html">Abetone, Province of Pistoia, Tuscany&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;Adamstown, Lancaster County, Pennsylvania</a>       /td>
  <td class=dt1><a href="by_city_245.html">Louth, Lincolnshire, England&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;Lucciana, Haute-Corse, Corsica</a></td>
  </tr>
  <tr><td class=dt1><a href="by_city_003.html">Adamswiller, Bas-Rhin, Alsace&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;Aghir, Djerba Island, Medenine Governorate</a>       </td>
  <td class=dt1><a href="by_city_246.html">Luccianna, Haute-Corse, Corsica&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;Lumellogno, Novara, Province of Novara, Piedmont</a></td>
  </tr>

我所追求的是从“by_city_001.html”到“by_city_486.html”的链接。这是我的代码:

  def scrapeCityList(pageUrl):

html = scraperwiki.scrape(pageUrl)
root = lxml.html.fromstring(html)

print html

links = root.cssselect('td.dt1 a')

for link in links:

    url = 'http://www.tripadvisor.co.uk' + link.attrib['href']
    print url 

在代码中调用如下:

  scrapeCityList('http://www.tripadvisor.co.uk/pages/by_city.html')

现在当我运行它时,它只会返回从 0045 开始的链接!

输出(045~486)

http://www.tripadvisor.co.ukby_city_045.html
http://www.tripadvisor.co.ukby_city_288.html
http://www.tripadvisor.co.ukby_city_046.html
http://www.tripadvisor.co.ukby_city_289.html
http://www.tripadvisor.co.ukby_city_047.html
http://www.tripadvisor.co.ukby_city_290.html and so on...

我尝试将选择器更改为:

  links = root.cssselect('td.dt1')

它会像这样抓取 487 个“元素”:

<Element td at 0x13d75f0>
<Element td at 0x13d7650>
<Element td at 0x13d76b0>

但我无法从中获取“href”值。当我在 cssselect 行中选择“a”时,我无法弄清楚为什么它会丢失前 44 个链接。我看过代码,但我不知道。

提前感谢您的帮助!

克莱尔

【问题讨论】:

    标签: python web-scraping lxml scraperwiki


    【解决方案1】:

    您的代码运行良好。你可以在这里看到它的实际效果:https://scraperwiki.com/scrapers/tripadvisor_cities/

    我添加了保存到数据存储区,因此您可以看到它实际上处理了所有链接。

    import scraperwiki
    import lxml.html
    
        def scrapeCityList(pageUrl):
        html = scraperwiki.scrape(pageUrl)
        root = lxml.html.fromstring(html)
        links = root.cssselect('td.dt1 a')
        print len(links)
        batch = []
        for link in links[1:]: #skip the first link since it's only a link to tripadvisor and not a subpage
            record = {}
            url = 'http://www.tripadvisor.co.uk/' + link.attrib['href']
            record['url'] = url
            batch.append(record)
        scraperwiki.sqlite.save(["url"],data=batch)
    
    scrapeCityList('http://www.tripadvisor.co.uk/pages/by_city.html') 
    

    如果你使用第二个 css 选择器:

    links = root.cssselect('td.dt1')
    

    那么您选择的是 td 元素而不是 a 元素(它是 td 的子元素)。您可以通过以下方式选择 a:

    url = 'http://www.tripadvisor.co.uk/' + link[0].attrib['href']
    

    您选择 td 的第一个子元素的位置(即 [0])。

    如果您想查看 lxml.html 中元素的所有属性,请使用:

    print element.attrib
    

    对于 td 给出:

    {'class': 'dt1'}
    {'class': 'dt1'}
    {'class': 'dt1'}
    ...
    

    对于 a:

    {'href': 'by_city_001.html'}
    {'href': 'by_city_244.html'}
    {'href': 'by_city_002.html'}
    ...
    

    【讨论】:

    • 感谢您的回答,这让我无谓地发疯,有时我认为您只需要这种保证!
    猜你喜欢
    • 1970-01-01
    • 2015-06-07
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-03
    相关资源
    最近更新 更多