我们在python3 爬虫学习:爬取豆瓣读书Top250(三)中已经爬到我们需要的几个数据,但是代码略显杂乱,输出的结果也并没有跟书本一一对应,所以这节课就要把这些问题统统解决掉。
CSS选择器
在html
的CSS选择器
中,用‘#’
代表‘id’
,用‘.’
代表‘class’
。
比如:‘#name’
表示所有‘id='name' ’
的元素,‘.title’
表示所有‘class='title'’
的元素。
当‘#’
和‘.’
组合在一起用时,他们表示的是同时符合条件的标签元素,例如:
<div id = 'name' class = 'title' class = 'book'>
<p class = 'pl'>......</p>
</div>
上面的例子用CSS选择器表示就是‘#name.title’
或者‘.title.book’
,注意这中间不能有空格,不然就是另一个意思了!
当两个选择器中间有空格时,它表示一个子元素选择器。
我们还是以上面的例子来表述,当我们想要选择所有‘id = 'name'’
的<div>标签里面的‘class = 'pl'’
的<p>标签时,就可以写成‘#name .pl’
,即嵌套在‘id = 'name'’
的<div>标签里面的‘class = 'pl'’
的<p>标签。
嵌套可以是任意层级,只要后面那个选择器在前面的选择器里面。如果只需要直接嵌套在第一层符合条件的元素,可以用 > 分隔。比如:.item > .book。
我们使用BeautifulSoup
对象的select()
方法,将CSS选择器
作为参数传入到select()
里面,可以把下面的例子改写一下:
#查找所有属性为class = 'pl2' 的 div 标签
items = bs.find_all('div' , class_ = 'pl2')
for i in items:
#查找 class_='pl2' 的 div 标签中的 a 标签
tag = i.find('a')
#获取a标签的文本内容用tag.text,但是这里还可以这样写:获取a标签的title属性的值
name = tag['title']
#获取a标签的href属性的值
link = tag['href']
#字符串格式化,使用\n换行
print('书名:{}\n链接:{}' .format(name , link))
改写后例子:
#查找所有属性为class = 'pl2' 的 div 标签
items = bs.select('div.pl2 a')
for i in items:
#获取a标签的文本内容用i.text,但是这里还可以这样写:获取a标签的title属性的值
name = i['title']
#获取a标签的href属性的值
link = i['href']
#字符串格式化,使用\n换行
print('书名:{}\n链接:{}' .format(name , link))
我们将所有代码组合到一起:
# 导入requests、BeautifulSoup、time库
import requests
from bs4 import BeautifulSoup
import time
# 将用户代理信息放入请求头中,把爬虫伪装成浏览器,注意不要忘记键值对需要加上''
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.162 Safari/537.36'
}
# 将目标地址存入变量url
url = 'https://book.douban.com/top250'
# 以get方法获取网页数据并将response对象存入res
res = requests.get(url , headers = headers)
# 建立BeautifulSoup对象
bs = BeautifulSoup(res.text , 'html.parser')
# 提取所有class = 'pl2'的div标签里面的a标签
items = bs.select('div.pl2 a')
# 提取所有class = 'pl'的p标签
authors = bs.select('p.pl')
# 提取所有class = 'inq'的span标签
abstract = bs.select('span.inq')
# 使用zip函数,遍历多个列表
for i , j , k in zip(items , authors , abstract):
# 字符串格式化,使用\n换行
print('书名:{}\n链接:{}\n{}\n推荐语:{}'.format(i['title'] , i['href'] , j.text , k.text))
# 打印一行分隔符,让输出结果更美观
print('--------------------------------')
输出结果
网友评论