【问题标题】:Trouble printing all items from a list in python无法打印python列表中的所有项目
【发布时间】:2014-07-09 11:33:26
【问题描述】:

我正在尝试学习如何进行网络抓取,但它并没有以我希望的格式出现。这是我遇到的问题:

import urllib
import re

pagelist = ["page=1","page=2","page=3","page=4","page=5","page=6","page=7","page=8","page=9","page=10"]
ziplocations = ["=30008","=30009"]

i=0
while i<len(pagelist):
    url = "http://www.boostmobile.com/stores/?" +pagelist[i]+"&zipcode=30008"
    htmlfile = urllib.urlopen(url)
    htmltext = htmlfile.read()
    regex = '<h2 style="float:left;">(.+?)</h2>' 
    pattern = re.compile(regex)
    storeName = re.findall(pattern,htmltext)
    print "Store Name=", storeName[i]
    i+=1

此代码产生以下结果: 店铺名称 = Boost Mobile store by wireless depot 店铺名称 = 沃尔玛 ...... 所以对于 10 家不同的商店,我假设发生这种情况是因为

while i<len(pagelist):

只有=到十

所以它只打印出十个商店,而不是所有页面上列出的所有商店。

当我将倒数第二行更改为此

print storeName

它将打印出每个页面上列出的每个商店名称,但不是上面的格式,而是像这样: 'Boost mobile store by wireless depot','boost mobile store by kob wireless','marietta check chashing services',......等等大约另外120个条目。 那么如何以所需的格式获得它:“Store Name = ....”而不是:'name','name',.....

【问题讨论】:

    标签: python html regex web-scraping html-parsing


    【解决方案1】:

    storeName 是一个数组,你需要循环遍历它。目前,您使用页码在每个页面上对其进行一次索引,这可能不是您的意图。

    这是您的代码的正确版本,添加了循环。

    import urllib
    import re
    
    pagelist = ["page=1","page=2","page=3","page=4","page=5","page=6","page=7","page=8","page=9","page=10"]
    ziplocations = ["=30008","=30009"]
    
    i=0
    while i<len(pagelist):
        url = "http://www.boostmobile.com/stores/?" +pagelist[i]+"&zipcode=30008"
        htmlfile = urllib.urlopen(url)
        htmltext = htmlfile.read()
        regex = '<h2 style="float:left;">(.+?)</h2>' 
        pattern = re.compile(regex)
        storeName = re.findall(pattern,htmltext)
        for sn in storeName:
            print "Store Name=", sn
        i+=1
    

    【讨论】:

      【解决方案2】:

      Do not parse HTML with regex. 使用专用工具 - HTML Parser

      这是使用BeautifulSoup的解决方案:

      import urllib2
      from bs4 import BeautifulSoup
      
      base_url = "http://www.boostmobile.com/stores/?page={page}&zipcode={zipcode}"
      num_pages = 10
      zipcode = 30008
      
      for page in xrange(1, num_pages + 1):
          url = base_url.format(page=page, zipcode=zipcode)
          soup = BeautifulSoup(urllib2.urlopen(url))
      
          print "Page Number: %s" % page
          results = soup.find('table', class_="results")
          for h2 in results.find_all('h2'):
              print h2.text
      

      打印出来:

      Page Number: 1
      Boost Mobile Store by Wireless Depot
      Boost Mobile Store by KOB Wireless
      Marietta Check Cashing Services
      ...
      Page Number: 2
      Target
      Wal-Mart
      ...
      

      如您所见,首先我们找到一个带有results 类的table 标签——这就是商店名称的实际所在。然后,在table 中,我们可以找到所有h2 标记。这比依赖标签的style 属性更可靠。


      您也可以使用SoupStrainer。它会提高性能,因为它只会解析您指定的文档部分:

      required_part = SoupStrainer('table', class_="results")
      for page in xrange(1, num_pages + 1):
          url = base_url.format(page=page, zipcode=zipcode)
          soup = BeautifulSoup(urllib2.urlopen(url), parse_only=required_part)
      
          print "Page Number: %s" % page
          for h2 in soup.find_all('h2'):
              print h2.text
      

      这里我们说:“只解析带有results 类的table 标记。然后给我们其中的所有h2 标记。”

      另外,如果你想提高性能,可以let BeautifulSoup use lxml parser under the hood

      soup = BeautifulSoup(urllib2.urlopen(url), "lxml", parse_only=required_part) 
      

      希望对您有所帮助。

      【讨论】:

      • 太棒了!谢谢,我还是有问题。我试图让它通过几个邮政编码。是不是就这么简单 url = base_url.format(page=page, zipcode=(variable))
      • @SamK 是的,您可能需要使用嵌套循环。如果您需要帮助,请告诉我。
      • 是的,我一定没有正确嵌套它们,你介意告诉我怎么做吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-24
      • 2023-01-22
      • 1970-01-01
      • 2021-05-25
      • 1970-01-01
      相关资源
      最近更新 更多