用python爬取豆瓣小说

第一次使用python爬取网页数据,虽然代码很简单,而且调试了蛮久的。但是蛮有意义的,故记录一下。

使用的是BeautifulSoup

# -*- coding:utf-8 -*-
from bs4 import BeautifulSoup
from urllib2 import urlopen, HTTPError, URLError

def getUrl(url):
    try:
        html = urlopen("https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4" + "?" + url)
    except (HTTPError,URLError):
        return None
    try:
        bsObj = BeautifulSoup(html.read(),from_encoding="utf8")
    except AttributeError as e :
        return None
    return bsObj

#截取页面上的书籍名称,评分,评分人数
def getAll(bsObj):
    qu = []   #使用列表记录这个页面符合要求的书籍
    try:
        allSubject = bsObj.findAll("li", {"class":"subject-item"})
        for i in allSubject:
            # 获取书籍名称
            j =  i.find("h2").find("a")
            name = j.attrs['title']

            # 获取评分
            k = i.find("span", {"class": "rating_nums"})
            score = float(k.get_text())

            # 获取评价人数,因为评价人数不止是有数字,还有中文,因此用filter截取数字
            g = i.find("span", {"class": "pl"})
            peo = g.get_text().encode('utf-8')
            people = int(filter(str.isdigit,peo))

            # 判断人数和评分是否符合要求
            if people >= 30000 and score >= 8.5:
                qu.append([name, score, people])
        return qu

    except AttributeError as e:
        return None

def main():
    All = []
    # 这里我只截取了一页的数据来测试,但是可以将第二个20改成更大的数字
    for i in range(0, 20, 20):

        bsObj = getUrl("start=" + str(i) + "&type=T")
        if bsObj is None:
            print "what?"
        else:
            k = getAll(bsObj)
            if k is not None:
                All.append(k)

    for i in All:
        for j in i:
            print j[0], j[1], j[2]

main()

这里提出遇到的问题以及解决的方法:

问题:
1.首先是评价人数获取的时候,真正的是(XXX人评价),但是我们只需要XXX这个数据。
2.是遇到的编码问题,一开始为了测试,直接输出了All也就是所有的保存的数据,但是发现书籍名称是以Unicode输出的。

方法:
1.在网上搜索了python在字符串中截取数字的方法,挑选了filter()这个函数。

filter()定义如下:
filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。
该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。

这里还有一个问题,那就是截取数据的时候记得改变编码,
peo = g.get_text().encode(‘utf-8’)
不然单单是g.get_text()是Unicode的类型的。

2.这个问题就比较白痴了,钻进了死胡同,一直奇怪为什么中文的输出是Unicode,后来恍然大悟,是因为我直接输出了它在列表中的编码,所以直接根据索引输出就行,会变成中文。但是还是记录一下,以此来警戒之后的自己。

由于是第一次爬取数据,因此代码比较简单。

猜你喜欢

转载自blog.csdn.net/RebelHero/article/details/78473504
今日推荐