无法打印python中列表中的所有项目

时间:2014-05-21 01:55:07

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

我正在尝试学习如何进行网页抓取,并且它不会以我希望的格式出现。以下是我遇到的问题:

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

此代码生成此结果: Store Name =通过无线仓库增加移动商店 商店名称=沃尔玛 ..... 对于10家不同的商店,我假设发生这种情况是因为

while i<len(pagelist):

仅为=到十

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

当我将第二行更改为此

print storeName

它会打印出每个页面上列出的每个商店名称,但不会采用上面的格式,但是会像这样: &#39;通过无线仓库提升移动商店,通过kob wireless&#39;提升移动商店&#39; marietta检查混乱服务&#39;,.....等等另外120个条目。 那么我如何得到所需的格式:&#34;商店名称= ....&#34;而不是:&#39; name&#39;,&#39; name&#39;,.....

2 个答案:

答案 0 :(得分: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
...

正如您所看到的,首先我们找到一个带有table类的results标记 - 这就是商店名称的实际位置。然后,在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

我们在这里说:&#34;仅解析table个标记results。并在其中提供所有h2标记。&#34;

此外,如果您想提高效果,可以let BeautifulSoup use lxml parser under the hood

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

希望有所帮助。

答案 1 :(得分: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