Python爬虫快速入门,静态网页爬取( 三 )


深入思考一下不难发现,书名在class="item"的div标签里的a标签内 。我们只要先找到所有class="item"的div标签,然后再找到其中的a标签即可,因此我们可以像下面这样来获取书名的数据:
items = soup.find_all('div', class_='item')for item in items: print(item.find('a'))输出结果:
<a href=https://www.isolves.com/it/cxkf/yy/Python/2020-08-25/"https://book.douban.com/subject/1007305/">红楼梦百年孤独白夜行这样,我们就找到了所有书名的数据 。但此时返回的还是Tag对象 。如果我们只想要书名和对应的链接呢?这就用到了Tag对象的text属性和HTML属性名取值 。
items = soup.find_all('div', class_='item')for item in items:tag = item.find('a')name = tag.textlink = tag['href']print(name, link)输出结果:
红楼梦 https://book.douban.com/subject/1007305/百年孤独 https://book.douban.com/subject/6082808/白夜行 https://book.douban.com/subject/10554308/我们通过Tag对象的text属性拿到了a标签里的文字内容,即红楼梦等 。然后我们通过和字典取值一样的方式,将HTML属性名作为键,得到了对应属性的值 。这里是以href属性为例,其他的HTML属性也同样可以 。
Tag对象的常用属性和方法总结如下:
属性/方法作用tag.find()返回符合条件的首个数据tag.find_all()返回符合条件的所有数据tag.text获取标签的文本内容tag[‘属性名’]获取标签属性的值
我们通过多次调用find()或find_all()方法一层层地找到了我们需要的数据 。那有没有什么方法可以直接就找到我们需要的数据,而不用多次查找吗?
答案是肯定的,这就需要用到css选择器了 。
2.3 CSS选择器在CSS选择器中,#代表id,.代表class 。比如:#a表示id=‘a’的所有元素,.b表示class=‘b’的所有元素 。当然,我们也可以直接通过标签名选择对应的元素,例如:a表示所有的a元素 。
事实上,它们还可以组合在一起,选择同时符合条件的元素,比如:a#b表示所有id=‘b’的a元素,d.c 表示所有class=‘c’的d元素,#b.c 表示所有 id=‘b’ 且 class=‘c’ 的元素,.c.f 表示所有class同时为c和f的元素 。
需要注意的是,选择同时符合条件的元素,选择器之间不能有空格,如果写成.c .f就是另一个意思了 。这是因为,当两个选择器之间加了空格,表示子元素选择 。还是以.c .f为例,它表示选择所有class=‘c’的元素里面class=‘f’的元素,即嵌套在class=‘c’的元素里面class=‘f’的元素 。这个嵌套可以是任意层级的,只要在里面就行,不要求直接嵌套在第一层 。如果只需要直接嵌套在第一层符合条件的元素,可以用>分隔,例如:.c > .f 。
我们来通过一个例子了解一下CSS选择器的用法:
from bs4 import BeautifulSouphtml = '''<div class="item"><p class="book">红楼梦</p><div class="hot"><p class="book">白夜行</p></div></div>'''soup = BeautifulSoup(html, 'html.parser')print(soup.select('.item.book'))print(soup.select('.item .book'))print(soup.select('.item > .book'))输出结果:
[][<p class="book">红楼梦</p>, <p class="book">白夜行</p>][<p class="book">红楼梦</p>]BeautifulSoup对象有一个select()方法,我们将CSS 选择器传进去即可直接找到我们需要的元素 。之前查找在class="item"的div标签里的a标签的代码就可以这样写:
items = soup.select('div.item a')for item in items:name = item.textlink = item['href']print(name, link)可以看到,我们一次性就将所有符合条件的a元素找了出来,同样的功能,代码变得更加简洁了 。
三、单个网页爬取学习到这里,现在你应该可以独自完成爬取豆瓣图书的任务了,豆瓣图书Top250地址:https://book.douban.com/top250 。
接下来我会给出具体的思路,不过建议你先尝试独立完成这个任务 。
首先,此前我们已经提到过,豆瓣是禁止反爬虫的,我们通过修改User-Agent伪装成浏览器成功“骗过”了豆瓣的识别:
import requestsfrom bs4 import BeautifulSoupheaders = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36'}re = requests.get('https://book.douban.com/top250', headers=headers)soup = BeautifulSoup(re.text, 'html.parser')


推荐阅读