赞
踩
(1)安装python,并安装jupyter库,便于使用jupyter notebook编辑页面
(2)安装python,可能需要配置环境变量,win10配置环境变量时,直接加一条新的路径
(3)安装好jupyter后,进入时先用命令进入jupyter库所在目录,再直接输入jupyter notebook,便可直接进入jupyter的网络编辑页面
例如:
cd
#进入jupyter库所在c盘
cd 目录
#进入jupyter库所在目录
再输入jupyter notebook
结果如下:
出现此界面后便会自动跳转到jupyter的网络编辑页面,如下:
分析URL链接:
第一页:https://movie.douban.com/top250 或 https://movie.douban.com/top250?start=0&filter=
第二页:https://movie.douban.com/top250?start=25&filter=
第三页:https://movie.douban.com/top250?start=50&filter=
第四页:https://movie.douban.com/top250?start=75&filter=
分析结果:从此可以看出,一至四页的URL链接是有规律 的,star=的后面,每个链接之间相差数字25
此时直接看第十页:
第十页URL为:
https://movie.douban.com /top250?start=225&filter=
再看第一页的链接为:
https://movie.douban.com/top250?start=0&filter=
仍然符合以上分析结果
结果如下:
将函数改为:
for page in range(0, 226, 25):
url=‘https://movie.douban.com/top250?start=%s&filter=’%page
将start=0改为start=%s,后面跟的%page表示将page函数中的数 值范围赋予给s,即可一次性构造出十个网页的链接
运行结果如下:
此时可随便点击一个链接进去,如点击start=75的链接进去,便进到top250 的第四页,而根据前面的分析,这个链接确实是第四页
实现这个目的,需要在python中安装request库,命令为pip install requests
以请求第一页为例:
test_url='https://movie.douban.com/top250?start=0&filter='
此处的单引号也可以写成双引号,目的都是为了把括号内的内容变为字符串
右击进入检查元素,点击网络(network),再点击所有(All)
对该网页进行刷新,下方会出现网页的组成元素,例如图片等
按上一步操作后,点击下图中的第一页的链接,再点击右边的消息头,可看到请求网址以及请求方法
test_url=’ https://movie.douban.com/top250?start=0&filter=’
requests.get(url= test_url)
requests表示库名,.get表示请求方法(网页中看到的是get),括号中的内容为第一页的链接
结果如下:
结果显示为418,浏览器识别出这个语句是爬虫程序,故拒绝返回值给我们
若改为
test_url=’ https://movie.douban.com/top250?start=0&filter=’
requests.get(url= test_url).text
同样返回不了值
将程序伪装成正常的用户访问,躲过浏览器的识别,以便成功获取数据
首先,将代码审查中的用户代理复制过来,并将其够造成一个字典
用户代理为:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0
test_url=’ https://movie.douban.com/top250?start=0&filter=’
#设置浏览器代理,构造字典:
‘User-Agent’: ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0’
#字典的构造方法:’a‘:‘b’
将字典放入括号内
requests.get(url= test_url, headers=headers).text
(代码后加.text便会返回全部内容,不加的话只返回总行数)
结果如下:
还可将
requests.get(url= test_url, headers=headers).text
的内容赋给一个值
例如:
reponse= requests.get(url= test_url, headers=headers).text
此时再运行,没有显示,但是如果将它单独拿到下一行可以运行出内容,
运行结果如下:
运行出来的结果双击可隐藏
也可执行单独在一行print(reponse)
来输出内容,输出的内容格式是排列好的
可供选择的分析工具有:
xpath
(重点介绍)
re(正则)
算法较复杂,xpath
解决不了时考虑用这个,下面也会提到
BeautifulSoup,即BS4
安装命令pip install lxml
from lxml import etree
html_etree = etree.HTML (reponse)
print(html_etree )
html_etree
为自己命名,可随便写HTML
必须为大写(以提取‘风华绝代’四个字为例)
其中,
html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li[2]/div/div[2]/div[2]/p[2]/span/text()')
语句,html_etree
为上述自己命名的过滤信息,.xpath
表示使用该方法,
语句语法格式:
过滤名.xpath('要提取信息的xpath路径')
/text()
过滤名.xpath('要提取信息的xpath路径/text()')
显示结果如上图[]
去掉,则在语句后加[0]
过滤名.xpath('要提取信息的xpath路径/text()')[0]
结果如下图所示xpath
路径?xpath
即可。打开网页,右击检查元素,找到每个电影模块对应的序列代码,如下图
将图中右侧鼠标选中的位置的xpath
路径复制下来为:
/html/body/div[3]/div[1]/div/div[1]/ol/li[1]
依次,第二个的xpath
路径为:
/html/body/div[3]/div[1]/div/div[1]/ol/li[2]
第三个的xpath
路径为:
/html/body/div[3]/div[1]/div/div[1]/ol/li[3]
……
最后一个的xpath
路径为:
/html/body/div[3]/div[1]/div/div[1]/ol/li[25]
由此可发现,它们的xpath
路径是有规律的,即最后一个[]
中的数字从1开始,增加到25
html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li[2]')
将语句后的[数字]删除,便可表示所有的xpath
路径
即html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li')
此时运行结果为:
下方共有25个返回值,li
为自己写的赋值,可用len()
函数查看返回值的长度
如下图:
25个路径里面,每个路径里面有10个电影影的名字,共250个
li=html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li')
for item in li:
name=item.xpath('')
item
为自己命名的,可理解为电影name
理解为电影名字xpath
路径里面获取得250个电影,然后再从这250个电影(item
)的xpath
路径里面获取250个电影名(name
)/html/body/div[3]/div[1]/div/div[1]/ol/li[1]/div/div[2]/div[1]/a/span[1]
第一页的霸王别姬:
/html/body/div[3]/div[1]/div/div[1]/ol/li[2]/div/div[2]/div[1]/a/span[1]
可看出,两个链接只有/li[]
中的数字不一样
代码表示:
li=html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li')
for item in li:
name=item.xpath('./div/div[2]/div[1]/a/span[1]')
此处的点表示上面写的li
后面括号里跟的所有路径,因为此处name
后面写的是第一页的名字的共同特征,故只输出第一页的所有电影名字,结果如下:
跟上面提取‘风华绝代’之时一样,上图中显示的结果为一个数组,可在代码后加[0]
,输出纯文字,如下图所示:
先复制两个电影链接进行分析,以第一页为例(大致做法和获取名字相同)
第一页的肖申克的救赎:
/html/body/div[3]/div[1]/div/div[1]/ol/li[1]/div/div[2]/div[1]/a
第一页的霸王别姬:
/html/body/div[3]/div[1]/div/div[1]/ol/li[2]/div/div[2]/div[1]/a
可看出,两个链接只有/li[]
中的数字不一样
代码表示:
li=html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li')
for item in li:
dy_url=item.xpath('./div/div[2]/div[1]/a/@href')[0]
此处的点表示上面写的li
后面括号里跟的所有路径,因为此处dy_url
(自己写的)后面写的是第一页的链接的共同特征,/@href
为输出链接时的后缀,与上述输出电影名字文本类型时的/text()
意义相同,程序中带有之前输出电影名字的部分,故只输出第一页的所有电影名字和电影链接,结果如下:
先复制两个电影星级数进行分析,以第一页为例(大致做法和(4)、(5)名字相同)
第一页的肖申克的救赎:
/html/body/div[3]/div[1]/div/div[1]/ol/li[1]/div/div[2]/div[2]/div/span[1]
第一页的霸王别姬:
/html/body/div[3]/div[1]/div/div[1]/ol/li[2]/div/div[2]/div[2]/div/span[1]
可看出,两个链接只有/li[]
中的数字不一样
代码表示:
li=html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li')
for item in li:
rating=item.xpath('./div/div[2]/div[2]/div/span[1]/@class')[0]
此处的点表示上面写的li
后面括号里跟的所有路径,因为此处rating
(自己写的)后面写的是第一页的星级数的共同特征,/@class
为输出星级数时的后缀,与上述输出电影名字文本类型时的/text()
意义相同,结果如下:
先复制两个电影评分进行分析,以第一页为例(大致做法和(4)、(5)、(6)名字相同)
第一页的肖申克的救赎:
/html/body/div[3]/div[1]/div/div[1]/ol/li[1]/div/div[2]/div[2]/div/span[2]
第一页的霸王别姬:
/html/body/div[3]/div[1]/div/div[1]/ol/li[2]/div/div[2]/div[2]/div/span[2]
可看出,两个链接只有/li[]中的数字不一样
代码表示:
li=html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li')
for item in li:
rating_num=item.xpath('./div/div[2]/div[2]/div/span[2]')
运行结果如下:
和上述方法一样,不再叙述
print("~"*90)
语句为输出分隔符,其中,*90
表示输出90个波浪符号,分隔符的长度横着排列,当长度超过屏幕长度时,会自动从第二行开始排列,分隔符类型还可以自己变换,如下图,换成90个——符号也可以
运行结果如下
不想输出的值可在print
前面加#
,变为注释,注释不运行
txt
,html
,涉及表格内容的可用excel
和csv
保存等
本次主要将上述爬取的内容放到csv格式中
为了方便保存,在电脑上建一个文件夹,然后在文件夹处输入cmd
命令进入控制台,这样可以在打开jupyter notebook
时直接打开之前写的代码
以上爬取的内容中,如评价人数中,显示的是人数和评价两个字,但很多时候我们只要数字,所以接下来将会介绍如何用正则表达式获取数字,以及爬取内容的保存问题
为了运行出来时好看,将爬取的排名放到爬取内容的第一个
如爬取到的星级数为rating5-t
或rating4.5-t
,但我们只想要数字,故用正则表达式来匹配
re
正则表达式语法较复杂,平时可在网上多学习
准备工作:引入re
包,import re
以分离rating5-t
为例,运行结果如下:
test
为自己命名,re.findall
为语法结构,原为:re.findall('rating5-t', test)
因为想要把5替换了,故将5的位置改为(.*?)
注意,re
查找替换内容的过程中,找的只是要替换内容的最近的两个边界,如上述图片中,若将括号内改为(‘ting(.*?)-’, test)
,和原来(‘rating(.*?)-t’, test)
相比,去掉了ra
和t
,仍能定位到5并运行出来,如下:
只要保留离5最近的g和-,其余在rating5-t
中的不论怎么变都能输出5
以提取“zzy旷love张kjh
”这句话中的zzy love kjh
为例
可以发现,最后的kjh
没有显示出来,因为从右边开始读取,kjh
后面找不到第一个边界(双引号不是语句中的内容,故不能作为kjh
的最近的边界),在kih
后面加上一个边界,(字母,文字,数字均可,此处我加了1314
),如下图
提取评价中的评价人数(从右边开始读取,故左边第一个没有边界照样能读出来)
上一步中是用(.*?)
的方法来提取需要的内容,接下来将介绍专门提取所需数字的re
正则表达式,运用时根据需求自主选择即可
快速注释及解除方法,Ctrl+/
注意此处的写法:
赋值时从右边开始,故图中rating1=rating2
但不等于rating3
,rating3=rating4
len(fen)
求的是fen
中数字的长度,而len()
函数中只能求字符串的长度,不能求数字的长度,故要用str()
函数将fen
转化为字符串,如下图导入csv
,可直接在一个import
后面一次性导入多个内容
运行后编辑页面下方没有内容出现,但是打开自己进入jupyter notebook
的新建文件夹处,出现了一个豆瓣250.csv的文件
打开豆瓣250.csv这个文件后,界面为:
打开时有可能为乱码,可将文件夹删除重新写入,或将encoding='utf-8-sig'
改为encoding='utf-8-sig'
将爬取所有内容放入豆瓣250.csv中(下列两张图为所有完整代码)
运行结果为:(共25个)
最后一行的fp.close()
不能写在for item in li:
的循环中,否则会被提前关闭
写入成功后打开豆瓣250.csv文件如下:
到此爬取豆瓣top250第一页数据并保存成功!
一次性获取页面上250个电影的内容,爬取所有250个页面的内容
#爬取所有250个页面的内容(所有代码综合) import re,csv,requests from lxml import etree #1.设置浏览器代理,构造字典 headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0' } #2.创建并打开文件夹,写入内容 fp = open("./豆瓣250.csv",'a',encoding='utf-8-sig') writer=csv.writer(fp) writer.writerow(('排名','名称','链接','星级','评分','评价人数')) #3.循环所有页面 for page in range(0, 226, 25): print("正在获取第%s页"%page) url='https://movie.douban.com/top250?start=%s&filter='%page # 4.请求源代码,向服务器发出请求 reponse=requests.get(url=url,headers=headers).text #5.看做筛子筛取数据 html_etree = etree.HTML (reponse) #6.过滤 li=html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li') for item in li: rank=item.xpath('./div/div[1]/em/text()')[0] #电影排名 name=item.xpath('./div/div[2]/div[1]/a/span[1]/text()')[0] #电影名字 dy_url=item.xpath('./div/div[2]/div[1]/a/@href')[0] #电影链接 rating=item.xpath('./div/div[2]/div[2]/div/span[1]/@class')[0] #电影星级数相关处理(如5星级) rating=re.findall('rating(.*?)-t', rating)[0] if len(rating)==2: #rating为字符串,故直接求长度 star = int(rating) / 10 #字符串不可做运算,故int()转化为整数型 else: star=rating rating_num=item.xpath('./div/div[2]/div[2]/div/span[2]/text()')[0] #电影分数(如9.0分) content=item.xpath('./div/div[2]/div[2]/div/span[4]/text()')[0] #电影评价人数(如1234人评价) content=re.sub(r'\D',"", content) #""中的替代部分可写可不写 # print(rank,name,dy_url,star,rating_num,content) writer.writerow((rank,name,dy_url,star,rating_num,content)) #写入身体部分内容 fp.close()
运行结果为:
注意,此处写入所有的电影内容,需要把之前的第一页获取产生的文件夹删除以后再做此操作,要不写入不成功
打开豆瓣250.csv,就有250个电影的信息了,如下图:
至此,爬取数据成功结束!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。