静态网页爬虫
解析数据
通过在命令行中输入 pip install beautifulsoup4 安装 BeautifulSoup
我们通过 from bs4 import BeautifulSoup 语句导入 BeautifulSoup,然后使用 BeautifulSoup(res.text, 'html.parser') 语句将网页源代码的字符串形式解析成了 BeautifulSoup 对象。
创建 BeautifulSoup 对象时需要传入两个参数,第一个参数是要解析的 HTML 文本,即网站源代码的字符串形式(res.text)。第二个参数是解析 HTML 的解析器,html.parser 是 Python 中内置的解析器
1 import requests 2 from bs4 import BeautifulSoup 3 4 headers = { 5 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36' 6 } 7 res = requests.get('https://book.douban.com/top250', headers=headers) 8 soup = BeautifulSoup(res.text, 'html.parser')
提取数据
find() 和 find_all() 的作用和区别:
我们通过多次调用 find() 或 find_all() 方法一层层地找到了我们需要的数据。你可能会问,有没有什么方法可以直接就找到我们需要的数据,而不用多次查找吗?
答案是肯定的,需要用到 CSS 选择器,
- 在 CSS 选择器中,# 代表 id,. 代表 class。比如:#login 表示 id='login' 的所有元素,.item 表示 class='item' 的所有元素。
- 它们也可以组合在一起,选择同时符合条件的元素,比如:a#login 表示所有 id='login' 的 a 元素,p.item 表示所有 class='item' 的 p 元素,#login.item 表示所有 id='login' 且 class='item' 的元素,.item.book 表示所有 class 同时为 item 和 book 的元素。
- 选择同时符合条件的元素,选择器之间不能有空格
- 当两个选择器之间加了空格,表示子元素选择。还是以 .item .book 为例,它表示选择所有 class='item' 的元素里面 class='book' 的元素,即嵌套在 class='item' 的元素里面 class='book' 的元素。这个嵌套可以是任意层级的,只要在里面就行,不要求直接嵌套在第一层。如果只需要直接嵌套在第一层符合条件的元素,可以用 > 分隔。比如:.item > .book。
来看个例子感受一下它们的区别:
1 from bs4 import BeautifulSoup 2 3 html = ''' 4 <div class="item"> 5 <p class="book">小王子</p> 6 <div class="hot"> 7 <p class="book">追风筝的人</p> 8 </div> 9 </div>''' 10 11 soup = BeautifulSoup(html, 'html.parser') 12 13 print(soup.select('.item.book')) 14 # 输出:[] 15 16 print(soup.select('.item .book')) 17 # 输出:[<p class="book">小王子</p>, <p class="book">追风筝的人</p>] 18 19 print(soup.select('.item > .book')) 20 # 输出:[<p class="book">小王子</p>]
BeautifulSoup 对象 有一个 select() 方法,我们将 CSS 选择器 传进去即可直接找到我们需要的元素。
1 import requests 2 from bs4 import BeautifulSoup 3 4 headers = { 5 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36' 6 } 7 res = requests.get('https://book.douban.com/top250', headers=headers) 8 soup = BeautifulSoup(res.text, 'html.parser') 9 items = soup.select('div.pl2 a') 10 for i in items: 11 # 提取书名 12 name = i['title'] 13 # 提取链接 14 link = i['href'] 15 print(name, link)
不使用Css选择器时:
1 import requests 2 from bs4 import BeautifulSoup 3 4 headers = { 5 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36' 6 } 7 res = requests.get('https://book.douban.com/top250', headers=headers) 8 soup = BeautifulSoup(res.text, 'html.parser') 9 items = soup.find_all('div', class_='pl2') 10 for i in items: 11 tag = i.find('a') 12 # 去掉空格和换行符 13 name = ''.join(tag.text.split()) 14 link = tag['href'] 15 print(name, link) 16 # 输出: 17 # 追风筝的人 https://book.douban.com/subject/1770782/ 18 # 解忧杂货店 https://book.douban.com/subject/25862578/ 19 # 小王子 https://book.douban.com/subject/1084336/ 20 # 白夜行 https://book.douban.com/subject/3259440/ 21 # 活着 https://book.douban.com/subject/4913064/ 22 # 嫌疑人X的献身 https://book.douban.com/subject/3211779/ 23 # 省略余下内容...
Tag 对象 的常用属性和方法:
解析数据:
一些 HTML 常见元素:
非自闭合元素和自闭合元素的区别:
HTML 元素属性:
在网页开发者工具中,找到网页内容对应的代码,并对其进行修改,伪造一张网页。
回首间---我错过了那片星海