Python爬虫第三课:我的人生第一只爬虫
一、BeautifulSoup模块
- Windows环境下运行,需要在命令提示符内运行代码:pip install bs4
- MacOS环境下需要输入pip3 install BeautifulSoup4
- requests库帮我们搞定了爬虫第1步——获取数据。
- HTML知识,则有助于我们解析和提取网页源代码中的数据。
- 本次,则掌握如何使用BeautifulSoup解析和提取网页中的数据。
二、解析数据与提取数据
我们平时使用浏览器上网,浏览器会把服务器返回来的HTML源代码翻译成我们能看懂的样子,之后我们才能阅读网页进行各种操作。
相应地,我们在爬虫要使用类似地工具,将HTML“翻译”成程序能读懂代码,我们才能通过程序提取到想要的数据。
【提取数据】是指把我们需要的数据从源数据中有针对性地挑选出来。
三、使用BeautifulSoup解析数据
- 在括号中,要输入两个参数,第1个参数是要被解析的文本,注意了,它必须必须必须是字符串类型的值或者变量!!!
- 括号中的第2个参数用来标识解析器,我们要用的是一个Python内置库:html.parser(它不是唯一的解析器,但是相对来说比较简单。其他的还有’lxml’等)。
import requests# 获取网页源代码,得到response对象
response = requests.get('https://xiaoke.kaikeba.com/example/canteen/index.html')
# 检查请求是否正确响应
print(response.status_code)
# 将response的内容以字符串的形式返回
html = response.text
# 打印html
print(html)
以上的内容是我们之前学习过的,下面用BeautifulSoup来解析网页数据。
import requests
# 引入bs库
from bs4 import BeautifulSoup# 获取网页源代码,得到response对象
response = requests.get('https://xiaoke.kaikeba.com/example/canteen/index.html')
# 检查请求是否正确响应
print(response.status_code)
# 将response的内容以字符串的形式返回
html = response.text
# 把网页解析为BeautifulSoup对象
bs_response = BeautifulSoup(html,'html.parser')
我们将soup的数据类型和soup本身用print函数进行输出.
import requests
# 引入bs库
from bs4 import BeautifulSoup# 获取网页源代码,得到response对象
response = requests.get('https://xiaoke.kaikeba.com/example/canteen/index.html')
# 检查请求是否正确响应
print(response.status_code)
# 将response的内容以字符串的形式返回
html = response.text
# 把网页解析为BeautifulSoup对象
bs_response = BeautifulSoup(html,'html.parser')
print(type(bs_response))
print(bs_response)输出结果如下:
200
<class 'bs4.BeautifulSoup'>
bs对象网页源代码过长,此处不予展示
- bs_response的数据类型是<class ‘bs4.BeautifulSoup’>,说明bs_response是一个BeautifulSoup对象。
- 仔细地观察,我们会发现,打印soup出来的源代码和我们之前使用response.text打印出来的源代码是完全一样的。
- 虽然我们使用了BeautifulSoup来解析数据,但从直观上来看,得到的结果竟然和没解析之前一样。
- 但是虽然response.text和soup打印出的内容,从表面上看长得一模一样,却有着不同的内心,它们属于不同的类:<class ‘str’> 与<class ‘bs4.BeautifulSoup’>。前者是字符串,后者是已经被解析过的BeautifulSoup对象。之所以打印出来的是一样的文本,是因为BeautifulSoup对象在直接打印它的时候会调用该对象内的str方法,所以直接打印 bs 对象显示字符串是str的返回结果。
四、使用BeautifulSoup提取数据
1. find()与find_all()
- find()与find_all()是BeautifulSoup对象的两个方法,它们可以匹配HTML的标签和属性,把BeautifulSoup对象里符合要求的数据都提取出来。
- 它俩的用法基本是一样的,区别在于,find()只提取首个满足要求的数据,而find_all()提取出的是所有满足要求的数据。
import requests
# 引入bs库
from bs4 import BeautifulSoup# 获取网页源代码,得到response对象
response = requests.get('https://xiaoke.kaikeba.com/example/canteen/index.html')
# 将response的内容以字符串的形式返回
html = response.text
# 把网页解析为BeautifulSoup对象
bs_response = BeautifulSoup(html,'html.parser')
# 使用find方法提取首个div元素,并放到变量item里
item = bs_response.find('div')
print(type(item))
print(item)# 输出结果:
<class 'bs4.element.Tag'>
div元素内容过多,不予展示
运行结果正是首个<div>元素!我们还打印了它的数据类型:<class ‘bs4.element.Tag’>,说明这是一个Tag类对象。
再来试试find_all()吧,它可以提取出网页中的全部三个
import requests
# 引入bs库
from bs4 import BeautifulSoup# 获取网页源代码,得到response对象
response = requests.get('https://xiaoke.kaikeba.com/example/canteen/index.html')
# 将response的内容以字符串的形式返回
html = response.text
# 把网页解析为BeautifulSoup对象
bs_response = BeautifulSoup(html,'html.parser')
# 使用find方法提取首个div元素,并放到变量item里
item = bs_response.find_all('div')
print(type(item))
print(item)# 输出结果如下:
<class 'bs4.element.ResultSet'>
find_all的结果以列表的形式输出了
三个<div>元素,它们一起组成了一个列表结构。打印items的类型,显示的是\<class ‘bs4.element.ResultSet’>,是一个ResultSet类的对象。其实是Tag对象以列表结构储存了起来,可以把它当做列表来处理。
- 练习:爬取网站https://xiaoke.kaikeba.com/example/canteen/index.html的三道菜、材料及步骤
import requests
from bs4 import BeautifulSoupresponse = requests.get('https://xiaoke.kaikeba.com/example/canteen/index.html')
# 将返回的数据转换成BS对象
bs_response = BeautifulSoup(response.text,'html.parser')
# 通过最小级父标签及属性,提取出包含三道菜信息的代码
foods = bs_response.find_all(class_='show-list-item')
# 打印出的结果为列表类型
print(foods)
打印出的列表并不是我们最终想要的东西,我们想要的是列表中的值,所以要想办法提取出列表中的每一个值。用for循环遍历列表,将其中的值提取出来。
import requests
from bs4 import BeautifulSoupresponse = requests.get('https://xiaoke.kaikeba.com/example/canteen/index.html')
# 将返回的数据转换成BS对象
bs_response = BeautifulSoup(response.text,'html.parser')
# 通过最小级父标签及属性,提取出包含三道菜信息的代码
foods = bs_response.find_all(class_='show-list-item')
# for循环遍历列表
for food in foods:print(food)
程序运行很顺利,结果正是那三道菜的<div>元素。
但是,我们现在打印出来的东西还不是我们最终想要的东西,因为我们打印出来的东西还含有HTML标签。
接着涉及提取数据中的另一个知识点——Tag对象。
2. Tag对象
刚才在网页中提取三道菜信息的代码可以继续进行。
import requests
from bs4 import BeautifulSoupresponse = requests.get('https://xiaoke.kaikeba.com/example/canteen/index.html')
# 将返回的数据转换成BS对象
bs_response = BeautifulSoup(response.text,'html.parser')
# 通过最小级父标签及属性,提取出包含三道菜信息的代码
foods = bs_response.find_all(class_='show-list-item')
# for循环遍历列表
for food in foods:# 分别提取标题、原材料、步骤的内容title = food.find(class_='desc-title')material =food.find(class_='desc-title')step = food.find(class_='desc-step')# 打印内容print(title,material,step)
运行结果的数据类型,又是三个<class ‘bs4.element.Tag’>,用find()提取出来的数据类型和刚才一样,还是Tag对象。
这时,可以用到Tag对象的另外两种属性——Tag.text,和Tag[‘属性名’]。
import requests
from bs4 import BeautifulSoupresponse = requests.get('https://xiaoke.kaikeba.com/example/canteen/index.html')
# 将返回的数据转换成BS对象
bs_response = BeautifulSoup(response.text,'html.parser')
# 通过最小级父标签及属性,提取出包含三道菜信息的代码
foods = bs_response.find_all(class_='show-list-item')
# for循环遍历列表
for food in foods:# 分别提取标题、原材料、步骤的内容title = food.find(class_='desc-title')material =food.find(class_='desc-title')step = food.find(class_='desc-step')# 打印内容print(title.text,'\n',material.text,'\n',step.text)
输出结果中有空格和换行,使用replace()替换空格与换行
import requests
from bs4 import BeautifulSoupresponse = requests.get('https://xiaoke.kaikeba.com/example/canteen/index.html')
# 将返回的数据转换成BS对象
bs_response = BeautifulSoup(response.text,'html.parser')
# 通过最小级父标签及属性,提取出包含三道菜信息的代码
foods = bs_response.find_all(class_='show-list-item')
# for循环遍历列表
for food in foods:# 分别提取标题、原材料、步骤的内容title = food.find(class_='desc-title')material =food.find(class_='desc-material')step = food.find(class_='desc-step')# 打印内容print(title.text.replace(' ',''),'\n',material.text.replace(' ',''),'\n',step.text.replace(' ',''))
五、总结
我们的操作对象是这样的:Response对象——字符串——BS对象。到这里,又产生了两条分岔:一条是BS对象——Tag对象;另一条是BS对象——列表——Tag对象。
六、练习
- 爬取豆瓣新片榜的电影数据。网址:https://movie.douban.com/chart
- 第一种方法:找到父级标签,组成列表,再从中分别提取每个电影的信息
# 引用requests库
import requests
# 引用Beautiful库
from bs4 import BeautifulSoup# 伪装请求头,避免反爬
headers = {'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36'}
# 向网站发起请求,返回response对象
response = requests.get('https://movie.douban.com/chart',headers=headers)
# 将返回的数据转换为BS对象
bs_response = BeautifulSoup(response.text,'html.parser')
# 通过每个电影代码块,找到最小父级标签
list_movie = bs_response.find_all('div',class_="pl2")
# 循环遍历列表
movies = []
for movie in list_movie:tag_a = movie.find('a')title = tag_a.text.replace(' ','').replace('\n','')url = tag_a['href']tag_p = movie.find(class_='pl')info = tag_p.text.replace(' ','').replace('\n','')rating = movie.find(class_="star clearfix").text.replace(' ','').replace('\n','')movies.append([title,url,info,rating])print(movies)
- 第二种方法:分别提取电影的信息,然后按顺序将信息组合起来,并将文件存入CSV中。
import requests
from bs4 import BeautifulSoup
import csv# 伪装请求头,避免反爬
headers = {'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36'}
# 使用get()获取response对象
reponse = requests.get('https://movie.douban.com/chart',headers=headers)
# 将字符串转换为bs对象
bs_response = BeautifulSoup(reponse.text,'html.parser')
# 使用find_all()找到所有的电影信息
tag_name = bs_response.find_all('div',class_='pl2')
# 找到包含电影基本信息的标签
tag_p = bs_response.find_all('p',class_='pl')
# 找到包含电影评价信息的标签
tag_div = bs_response.find_all('div',class_='star clearfix')# 创建文件"douban_film.csv,并以写入模式打开
myfile = open('douban_film.csv','w')
# 写入文件的对象
myfile_writer = csv.writer(myfile)
# 写入表头
movie_title = myfile_writer.writerow(['电影名称','网址URL','基本信息','评价信息'])# 循环提取电影标题、URL、评价、信息
for num in range(len(tag_name)):# 取得每个电影的名称title = tag_name[num].find('a').text.replace(' ','').replace('\n','')# 取得每个电影的URLurl = tag_name[num].find('a')['href']# 取得每个电影的基本信息info = tag_p[num].text.replace(' ','').replace('n','')# 取得每个电影的评价信息rating = tag_div[num].text.replace(' ','').replace('\n','')# 将每部电影分别写入文件的行中myfile_writer.writerow([title,url,info,rating])# 关闭文件
myfile.close()
- 爬取豆瓣电影TOP250的列表,并存入xlsx文件中。
import requests
from bs4 import BeautifulSoup
import openpyxl# 请求头,避免反爬
headers = {'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36'}
# 使用requests.get()获取response对象,循环更新每页的页码# 创建xlsx工作簿
wb = openpyxl.Workbook()
# 创建工作表
sheet = wb.active
# 将工作表命名为豆瓣电影250
sheet.title = '豆瓣电影TOP250'
# 添加工作表头
sheet.append(['序号', '电影名称', '网址URL', '导演/演员', '评价信息', '影片简介'])# 观察豆瓣TOP250的影片的URL,规律为每页间隔25.
for i in range(10):reponse = requests.get(f'https://movie.douban.com/top250?start={i * 25}&filter=', headers=headers)# 将返回的字符串转换为bs对象bs_movie = BeautifulSoup(reponse.text, 'html.parser')# 通过find_all找到包含电影信息的列表list_movie = bs_movie.find_all('div', class_='item')# 循环遍历列表,返回每个电影的信息for movie in list_movie:# 电影序号num = movie.find('em').text# 电影标题title = movie.find('div', class_='hd').find('a').text.replace(' ', '').replace('\n', '')# 电影网址URLurl = movie.find('a')['href']# 电影导演与演员director = movie.find('p').text.replace(' ', '').replace('\n', '')# 电影评价信息rating = movie.find('div', class_='star').text.replace(' ', '').replace('\n', '/')# 电影简介,因第248条没有简介信息返回,所以使用异常捕捉报错try:info = movie.find('p', class_='quote').text.replace('\n', '')except:info = None# 将电影信息逐行写入xlsx文件中sheet.append([num, title, url, director, rating, info])# 打印,以便发现问题print(num)print(title)print(director)print(rating)print(info)# 保存文件为"豆瓣点评TOP250.xlsx"
wb.save('豆瓣电影TOP250.xlsx')
# 关闭文件
wb.close()
Python爬虫第三课:我的人生第一只爬虫相关推荐
- Python学习第三课-基本数据类型
Python学习第三课-基本数据类型 一.基本概念 1.1表达式 1.2语句 1.3程序 1.4函数 内置函数 自定义函数 参数 返回值 二.标识符 2.1 关键字 2.2标识符概念 驼峰命名法 下划 ...
- Python基础第三课-基本数据类型
Python基础第三课-基本数据类型 1.几个基本概念 1.1 表达式 1.2 语句 1.3 程序(program) 1.4 函数(function) 2.标识符 2.1 关键字 2.2 标识符概念 ...
- 爬虫第三课 AJAX
获取AJAX加载的内容 有些网页内容使用AJAX请求加载,这种数据无法直接对网页url进行获取.但是只要记住,AJAX请求一般返回给网页的是JSON文件,只要对AJAX请求地址进行POST或GET,就 ...
- Python基础第三课
上节课讲的内容 变量.输入输出.选择语句 比较运算符: >,<,>=,<=,!=,==... 逻辑运算符: and or not 演示08_answer.py 石头剪刀布人机 ...
- python入门第三课(初中生学Python)
继续学习本专栏,请关注初中生学习python专栏
- html课做一个网页,菜鸟自学建站 HTML 第三课 制作我的第一个网页_html/css_WEB-ITnose...
上一课我们了解了Dreamweaver的工作界面,从这节课开始,我们由浅入深的开始学习网页的制作. 首先打开Dreamweaver,制作网页首先要新建一个文档,就像我们写文稿需要一张纸一样. 只有有了 ...
- C语言探索之旅 | 第一部分第三课:你的第一个程序
作者 谢恩铭,公众号「程序员联盟」. 转载请注明出处. 原文:https://www.jianshu.com/p/c73fecacd006 <C语言探索之旅>全系列 内容简介 前言 控制台 ...
- 使用 Python 简单获取电影天堂的电影数据 [第一个爬虫小测试]
一.要求 得到电影天堂的最新下载页面下的相关数据 点击打开 : 存储为 csv 格式的表格文件 二.可能遇到的bug和解决 使用正则表达式匹配到没有"<>"的情况 请求 ...
- 爬虫项目三:这才是B站爬虫的正确姿势,视频、评论、弹幕全部拿下
文章目录 前言 一.获取视频数据 二.获取评论数据 三.获取弹幕数据 四.自动下载视频 前言 获取B站UP主主页所有视频数据.评论数据.弹幕数据.视频 提示:以下是本篇文章正文内容,下面案例可供参考 ...
- python跟易语言的爬虫_新人Python,第一只爬虫,,我就只会re.findall,你咬我?
[Python] 纯文本查看 复制代码import requests import re import os # 设置浏览器引擎 headers ={ 'User-Agent': 'Mozilla/5 ...
最新文章
- php 数据库查询乱码,怎么解决php数据库查询乱码问题
- halcon的算子清点: Chapter 5 滤波
- Java获取系统文件类型图标并显示在JSP上
- OpenCV中cvWaitKey()函数注意事项
- linux安全运维(一)
- c#之task与thread区别及其使用
- 你觉得一个128g主力机用几年会到非换不可的程度?
- React.js 组件的 props vs state
- 更改 VSCode 字体
- 基于模板匹配的螺母检测(计算机视觉实验)
- 3.5.3 连接偏移量管理器
- 微信扫码支付 支付模式二
- C语言程序设计现代方法(第二版)十二章课后练习题部分答案
- html 在线打开pdf文件怎么打开,在HTML中打开pdf文件怎么打开
- Sqlmap 22.05.23.05
- 《Android源码设计模式解析与实战》读书笔记(十六)
- 为网站鼠标点击添加富强民主等内容Js代码
- 解决 Unable to determine application id: com.android.tools.idea.run.ApkProvisionException
- 34.发送ICMP时间戳请求
- 【Python绘图】学习绘图第一步,先要知道哪些操作是常用的