Skip to main content
 首页 » 编程设计

Python scraper (Scraperwiki) 只得到一半的表

2025年05月04日12davidwang456

我正在学习如何在 Scraperwiki 中使用 Python 编写爬虫。到目前为止一切顺利,但我已经花了几天时间挠头解决一个我无法解决的问题。我正在尝试从表中获取所有链接。它有效,但是从从 001 到 486 的链接列表中,它只在 045 开始抓取它们。url/源只是网站上的城市列表,源可以在这里看到:
http://www.tripadvisor.co.uk/pages/by_city.html具体的 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 个链接。我查看了代码,但没有任何线索。

在此先感谢您的帮助!

克莱尔

请您参考如下方法:

您的代码运行良好。你可以在这里看到它的实际效果: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'} 
...