【问题标题】:scraping a table and getting more info from a link抓取表格并从链接获取更多信息
【发布时间】:2014-05-15 23:13:39
【问题描述】:

我正在使用python 和beautifulsoup 来刮一张桌子……我可以很好地处理我需要的大部分信息。我要抓取的内容的缩短表。

<tr> <td><a href="/wiki/Joseph_Carter_Abbott" title="Joseph Carter Abbott">Joseph Carter  Abbott</a></td> <td>1868–1872</td> <td>North Carolina</td> <td><a href="/wiki/Republican_Party_(United_States)" title="Republican Party (United States)">Republican</a></td>
</tr> 
<tr> <td><a href="/wiki/James_Abdnor" title="James Abdnor">James Abdnor</a></td> <td>1981–1987</td> <td>South Dakota</td> <td><a href="/wiki/Republican_Party_(United_States)" title="Republican Party (United States)">Republican</a></td> </tr> <tr> <td><a href="/wiki/Hazel_Abel" title="Hazel Abel">Hazel Abel</a></td> <td>1954</td> <td>Nebraska</td> <td><a href="/wiki/Republican_Party_(United_States)" title="Republican Party (United States)">Republican</a></td> 
</tr>

http://en.wikipedia.org/wiki/List_of_former_United_States_senators

我想要姓名、描述、年份、州、政党。

描述是每个人页面上的第一段文字。我知道如何独立获取此信息,但我不知道如何将其与姓名、年份、州、政党集成,因为我必须导航到不同的页面。

哦,我需要将其写入 csv。

谢谢!

【问题讨论】:

  • 您必须编写一些代码来读取这两个网页并将其中包含的信息结合起来。哦,将其写入 CSV。

标签: python csv beautifulsoup


【解决方案1】:

如果您使用的是 BeautifulSoup,您将不会以有状态的、类似浏览器的方式导航到另一个页面,而只是通过像 wiki/name。所以你的代码可能看起来像

import urllib, csv

with open('out.csv','w') as f:

    csv_file = csv.writer(f)

    #loop through the rows of the table
    for row in senator_rows:
        name = get_name(row)

        ... #extract the other data from the <tr> elt

        senator_page_url = get_url(row)

        #get description from HTML text of senator's page
        description = get_description(get_html(senator_page_url))

        #write this row to the CSV file
        csv_file.writerow([name, ..., description])

#quick way to get the HTML text as string for given url
def get_html(url):
    return urllib.urlopen(url).read()

请注意,在 python 3.x 中,您将导入并使用 urllib.request 而不是 urllib,并且您必须解码 bytesread() 调用将返回。 听起来你知道如何填写我留下的其他 get_* 函数,所以我希望这会有所帮助!

【讨论】:

    【解决方案2】:

    只是为了解释@anrosent 的回答:在解析过程中发送请求是最好和最一致的方法之一。但是,获取描述的函数也必须正常运行,因为如果它返回 NoneType 错误,整个过程就会变得混乱。

    我这样做的方式是这样的(请注意,我使用的是 Requests 库而不是 urllib 或 urllib2,因为我对此更满意 - 随意根据自己的喜好更改它,逻辑是反正一样):

    from bs4 import BeautifulSoup as bsoup
    import requests as rq
    import csv
    
    ofile = open("presidents.csv", "wb")
    f = csv.writer(ofile)
    f.writerow(["Name","Description","Years","State","Party"])
    base_url = "http://en.wikipedia.org/wiki/List_of_former_United_States_senators"
    r = rq.get(base_url)
    soup = bsoup(r.content)
    all_tables = soup.find_all("table", class_="wikitable")
    
    def get_description(url):
        r = rq.get(url)
        soup = bsoup(r.content)
        desc = soup.find_all("p")[0].get_text().strip().encode("utf-8")
        return desc
    
    complete_list = []
    for table in all_tables:
        trs = table.find_all("tr")[1:] # Ignore the header row.
        for tr in trs:
            tds = tr.find_all("td")
            first = tds[0].find("a") 
            name = first.get_text().encode("utf-8")
            desc = get_description("http://en.wikipedia.org%s" % first["href"])
            years = tds[1].get_text().encode("utf-8")
            state = tds[2].get_text().encode("utf-8")
            party = tds[3].get_text().encode("utf-8")
            f.writerow([name, desc, years, state, party])
    
    ofile.close()
    

    但是,此尝试在 David Barton 之后的行结束。如果您查看页面,可能与他占用了自己的两行有关。这由您来解决。回溯如下:

    Traceback (most recent call last):
      File "/home/nanashi/Documents/Python 2.7/Scrapers/presidents.py", line 25, in <module>
        name = first.get_text().encode("utf-8")
    AttributeError: 'NoneType' object has no attribute 'get_text'
    

    另外,请注意我的get_description 函数在主进程之前的位置。这显然是因为您必须先定义函数。最后,我的get_description 功能还不够完美,因为如果个别页面中的第一个p 标记不是您想要的,它可能会失败。

    结果样本:

    注意错误的台词,比如 Maryon Allen 的描述。这也是你要解决的问题。

    希望这会为您指明正确的方向。

    【讨论】:

    • 哎呀!谢谢!抱歉我没有早点看到这个!我对这个网站成员的技能水平感到惊讶。我几天的工作只需要几分钟。
    • @user3485563 另外,请查看您之前的其他问题并接受是否有任何问题,谢谢。
    • 感谢您的接受。 @alecxe:谢谢。虽然这不是最好的答案,但也不错。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    • 1970-01-01
    • 2019-06-05
    • 2019-06-05
    相关资源
    最近更新 更多