第一次使用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,后来恍然大悟,是因为我直接输出了它在列表中的编码,所以直接根据索引输出就行,会变成中文。但是还是记录一下,以此来警戒之后的自己。
由于是第一次爬取数据,因此代码比较简单。