python,并安装jupyter库,便于使用jupyter notebook编辑页面。
2.建立环境新建一个文件夹,在文件夹的路径栏输入CMD进入命令提示符页面,输入 pip install jupyter安装jupter。
新建文件夹
进入命令提示符安装jupyter
安装完成后,在命令提示符中输入jupyter notebook进入编辑环境
(请勿关闭该窗口,否则打开的环境会被报错)
进入编辑环境
新建一个项目
打开后,如图所示
选取多页网页的链接,分析起规律
第一页:https://movie.douban.com/top250
第二页:https://movie.douban.com/top250?start=25&filter=
第三页:https://movie.douban.com/top250?start=50&filter=
第四页:https://movie.douban.com/top250?start=75&filter=
最后一页:https://movie.douban.com/top250?start=225&filter=
可以发现从第二页起,每一页的链接有变化的是“start=”后的数字,且每次变化的值都为25,我们可以反推第一页的网页链接为
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后的数值为255,在for循环中如果写的上限为255则取不到该值,需要往上加一个数,所以上限写为226
2.请求网页源代码实现这个目的,需要在python中安装request库,同样的也是在命令提示符中输入为pip install requests
在进行请求之前,我们需要到对应的网站上去查询该网页的请求网址、请求方法以及请求成功的状态码
查询上面参数的操作方法如下:
(1)在网页中点击鼠标右键,并点击检查
(2)点击检查后网页变为下列形式
(3)按照下列顺序点击,进入查看页面
(通常情况下需要刷新一遍网页才会出现相应的内容)
在这里我们可以看到,该网页的请求方式为GET,请求成功状态码为200。
(4)得到这些内容后,我们可以开始请求该网页了。
import requests
test_url=’ https://movie.douban.com/top250?start=0&filter=’
requests.get(url= test_url)
requests表示库名,.get表示请求方法(网页中看到的是get),括号中的内容为网页的链接
运行结果如下:
返回的值为418不是200,说明我们的方法出现了一些问题。浏览器识别出这个语句是爬虫程序,故拒绝返回值给我们,至此,我们需要伪装浏览器。
将程序伪装成正常的用户访问,躲过浏览器的识别,以便成功获取数据。
首先,将代码审查中的用户代理复制过来,并将其构造成一个字典。
(1)网页的用户代理查看方式
(2)在我们上面的代码中加入该代理
import requests
test_url = 'https://movie.douban.com/top250?start=0&filter='
headers = {
'User-Agent':' Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36'
}
reponse = requests.get(url= test_url,headers=headers).text
(将结果赋值给reponse,代码后加.text便会返回全部内容,不加的话只返回总行数)
运行结果如下:
鉴于我们爬取下来的网页的无用信息太多,我们需要进行筛选来选出自己所需的信息。在该部分我们需要用到lxml包,该包的导入方法也是在命令提示符中输入pip install lxml进行导入,我们要用到lxml库下的etree
引用etree的语句为:
from lxml import etree
html_etree = etree.HTML (reponse)
1.查看xpath路径
查找方式为:选中要提取的文字、右击检查元素、下方代码中显示出选中的文字后、在显示出的文字处右击复制,点击xpath即可,下面用图来介绍操作步骤
(1)打开网页,右击检查元素,找到每个电影模块对应的序列代码
(2)分析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]
/html/body/div[3]/div[1]/div/div[1]/ol/li[3]
/html/body/div[3]/div[1]/div/div[1]/ol/li[4]
/html/body/div[3]/div[1]/div/div[1]/ol/li[5]
…
/html/body/div[3]/div[1]/div/div[1]/ol/li[25]
可以发现它们的变化是有规律的,即最后一个[]中的数字从1开始,增加到25。
**将li后==[]==内的数字去掉就可以表示每一个电影的xpath路径了。
用代码表示为:
from lxml import etree
html_etree = etree.HTML(reponse)
li = html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li')
查看路径的个数我们可以输入==len(li)==来查看
这里以爬取电影的名字为例
li=html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li')
for item in li:
name=item.xpath('')
(item、name为自定义的名称,可以自由命名,这里我们爬取的为电影名,所以取叫name;整个语句可理解为,从25个xpath路径里面获取得250个电影,然后再从这250个电影(item)的xpath路径里面获取250个电影名)
我们先复制几个电影名的xpath路径进行分析
肖申克的救赎://*[@id="content"]/div/div[1]/ol/li[1]/div/div[2]/div[1]/a/span[1]
霸王别姬://*[@id="content"]/div/div[1]/ol/li[2]/div/div[2]/div[1]/a/span[1]
阿甘正传://*[@id="content"]/div/div[1]/ol/li[3]/div/div[2]/div[1]/a/span[1]
可以看出,两个链接只有/li[]中的数字不一样。
我们将电影名的xpath路径进行处理后写入代码:
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]')
上面代码name后括号之后有一个“.”,此处的点表示上面写的li前面括号里的所有路径,因为此处name后面写的是第一页的名字的共同特征,故只输出第一页的所有电影名字,结果如下:
在name括号最后添加了“[0]”是为了让结果输出为纯文字而不是数组
(在这里我们还爬取了电影的排名、链接、星级、评分、评价人数,其操作步骤都与上面爬取电影名称的方法相同,只是我们需要分析的链接发生了变化而已)
(1)纵向输出
其中“print(“-”*50)“为分隔符,*50表示为50个”-“,分隔的符号可以自己选择。
(2)横向输出
(不想输出的值可在print前面加==#==,变为注释,注释不会被运行)
(3)re正则表达式
很多时候我们想要的数据只想它是数字,但是结果往往都不是这样,就比如上面的评价人数中,每一个数据后面都有”人评价“三个字,这里我们学习了正则表达式匹配内容。
如爬取到的星级数为rating5-t或rating45-t,但我们只想要数字,故用正则表达式来匹配。
我们需要先导入re这个包,但是考虑到rating-45我们需要进行一定的处理来将其化为个位数。具体的代码如下:
import re
rating = re.findall('rating(.*?)-t', rating)[0]
if len(rating) == 2:
star = int(rating) / 10 #int()转化为数字
else:
star = rating
这里介绍一下,在”rating-5“中,我们只想要”5“这个数字,故而用(.*?)来表示想要提取内容的位置。
专门提取数字的re正则表达式。
在提取数字的方式中。re正则表达式有一种特殊的方式。
import re
num="1064521人评价"
result=re.sub(r'\D',"代替非数字内容",num)
print(result)
运行结果如下:
在评论代码中加入== content re.sub(r’\D’, “”, content),就可以只取数字了。
本次学习的是css的保存方式;
我们需要导入”csv“的包,具体代码如下:
import csv
# 创建文件夹并打开
fp = open("./豆瓣top250.csv", 'a', newline='', encoding = 'utf-8-sig')
writer = csv.writer(fp) #我要写入
# 写入内容
writer.writerow(('排名', '名称', '链接', '星级', '评分', '评价人数'))
#关闭文件夹
fp.close()
将代码带入之前写好的代码。注意fp.close()不能写在for item in li:的循环中,否则会被提前关闭。
import requests, csv, re
from lxml import etree
#设置浏览器代理,它是一个字典
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'
}
# 创建文件夹并打开
fp = open("./豆瓣top250.csv", 'a', newline='', encoding = 'utf-8-sig')
writer = csv.writer(fp) #我要写入
# 写入内容
writer.writerow(('排名', '名称', '链接', '星级', '评分', '评价人数'))
for page in range(0, 226, 25): #226
print ("正在获取第%s页"%page)
url = 'https://movie.douban.com/top250?start=%s&filter='%page
#请求源代码,向服务器发出请求,200代表成功,回退对其,Ctrl+]
reponse = requests.get(url = url, headers = headers).text
# 快捷键运行,Ctrl+Enter
html_etree = etree.HTML(reponse) # 看成一个筛子,树状
# 过滤
li = html_etree.xpath('//*[@id="content"]/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]
# print (dy_url)
#评分
rating = item.xpath('./div/div[2]/div[2]/div/span[1]/@class')[0]
rating = re.findall('rating(.*?)-t', rating)[0]
if len(rating) == 2:
star = int(rating) / 10 #int()转化为数字
else:
star = rating
# 注释ctrl+?
rating_num = item.xpath('./div/div[2]/div[2]/div/span[2]/text()')[0]
content = item.xpath('./div/div[2]/div[2]/div/span[4]/text()')[0]
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()
运行结果为:
爬取到此就结束了
爬取结束后,这时候我们最先开始创建的文件夹里就会出现一个csv文件
打开看看
内容显示出来了,说明爬取成功了。