我们需要从一个网页中爬取东西时,如果对网页中有什么东西、网页如何构成都不清楚,我们是很难进行爬取的,所以这一步是为了后面爬取的方便实施。
1.2如何分析网页在这里,我要爬取的是豆瓣Top250上的东西。首先,我们得进入该网页,查看它的网页结构。点击【下一页】,查看网页的URL(也就是它的链接),多换几页之后会发现有如下图所示规律:
首先我们需要安装jupyter,使用Win+R,弹出一个框,输入cmd之后弹出一个黑框(控制台),然后使用pip%20install%20jupyter命令安装jupyter,安装成功后在电脑的G盘中执行以下步骤即可打开编辑环境:
新建文件夹 在文件夹导航栏输入cmd回车 在弹出的黑框(控制台)中输入%20jupyter%20notebook 1.4生成链接利用我们发现的规律,使用for循环,生成链接,然后对生成的链接随便找几个来测试是否和原网页链接相同
for%20page%20in%20range(0,226,25):
%20%20%20%20url=%20'https://movie.douban.com/top250?start=%s&filter='%page
%20%20%20%20
2.请求网页
接下来就是向服务器发出请求了,我们先选择第一个链接来进行测试,完成本页所有内容的获取,然后再获取其他所有页面的信息
2.1导入包这里需要用到requests这个,没有安装的话需要安装这个包,安装步骤如下:#pip安装%20pip%20install%20requests-------->win+r,运行--------->cmd,回车-------->输入pip%20install%20requests
2.2设置浏览器代理在网页中点击右键,打开检查,选择Network,All,刷新网页,选择第一个文件,双击,选择headers
设置的浏览器代理必须为字典型,如:
headers={
%20%20%20%20'User-Agent':'Mozilla/5.0%20(Windows%20NT%2010.0;%20Win64;%20x64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/78.0.3904.87%20Safari/537.36'
}
2.3请求服务器
请求源代码,向服务器发出请求,200代表成功,使用get()获取
test_url%20是一个链接,第二个%20headers%20是用来做浏览器代理的内容
response=requests.get(url=test_url,headers=headers).text
2.4请求服务器代码汇总
#快捷键运行%20Ctrl+Enter
import%20requests
#pip安装%20pip%20install%20requests-------->win+r,运行--------->cmd,回车-------->输入pip%20install%20requests
test_url='https://movie.douban.com/top250?start=0&filter='%20#''格式化为字符串
#设置浏览器代理,一个字典
#请求源代码,向服务器发出请求,200代表成功
response=requests.get(url=test_url,headers=headers).text
3.xpath提取信息
xpath是按照HTML标签的方式进行定位的,谷歌浏览器自带有xpath,%20直接复制来就可以使用,简单方便,运行速度快
3.1获取xpath节点方法 3.2提取内容我们使用xpath时,也必须先对网页进行%20lxml%20库中的%20etree解析%20,把它变为特有的树状形式,才能通过它进行节点定位。未安装lxml包的需要安装
from%20lxml%20import%20%20etree
#安装,pip%20install%20lxml
html_etree=etree.HTML(response)#看成一个筛子,树状
3.2.1提取文本
当我们提取标签内的文本时,需要在复制到的xpath后面加上/text()%20,告诉它说我需要提取的内容是一个标签呈现的数据,如《肖申克的救赎》:
肖申克的救赎
对应的xpath为:
//*[@id="content"]/div/div[1]/ol/li[1]/div/div[2]/div[2]/div/span[1]
提取文字:
name%20=%20html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li[1]/div/div[2]/div[1]/a/span[1]/text()')
print%20(name)#数组形式
print%20(name[0])#字符串形式
结果为:
['肖申克的救赎']
肖申克的救赎
3.2.2提取链接
每一个链接都是在标签内的,通常放在src="%20"%20或者%20href="%20"%20之中,如:
xpath为:
//*[@id="content"]/div/div[1]/ol/li[1]/div/div[2]/div[1]/a
提取链接:
提取链接时,需要在复制到的xpath后面加上/@href%20,%20指定提取链接
dy_url%20=%20html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li[1]/div/div[2]/div[1]/a/@href')
print%20(dy_url)#数组形式
print%20(dy_url[0])#字符串形式
结果为
['https://movie.douban.com/subject/1292052/']
https://movie.douban.com/subject/1292052/
3.2.3提取标签元素
这个网页中电影的星级没有用几颗星的文本表示,而是标签表示的,其中,满星的表示和非满星的表示的标签不一样,如:
所以只需要取出%20class="%20"中的内容就可以得到星级了,复制它的xpath,和提取链接的方法一样,在后面加上%20/@class%20即可
rating%20=%20html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li[1]/div/div[2]/div[2]/div/span[1]/@class')
print%20(rating)#数组形式
print%20(rating[0])#字符串形式
结果为:
['rating5-t']
rating5-t
3.2.4提取评论人数
xpath为:
//*[@id="content"]/div/div[1]/ol/li[4]/div/div[2]/div[2]/div/span[4]
提取人数
rating_num%20=%20html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li[4]/div/div[2]/div[2]/div/span[4]/text()')
print%20(rating_num)#数组形式
print%20(rating_num[0])#字符串形式
结果为:
['1689452人评价']
1689452人评价
4.正则表达式匹配信息
4.1%20正则表达式匹配星级
我们需要把结果中的信息匹配出来,可以使用正则表达式,单独提取自己需要的信息,如星级,它都是以%20rating5-t%20方式呈现的,但是我们只需要它数字5位置的部分,所以需要进行二次提取。正则表达式中需要提取出来的地方用%20(.*?)%20替代,如
import%20re
test%20=%20"rating5-t"
text%20=%20re.findall('rating(.*?)-t',%20test)
print%20(text)
结果为:
['5']
4.2正则表达式匹配评论人数
我们在前面xpath提取到的数据格式为:%201056830人评价%20,保存的时候只需要数字即可,现在把数字提取出来:
test="1971789人评价"
text=re.findall('(.*?)人评价',test)
print(text[0])
结果为:
1971789
4.3区分星级
5------------>5分%20%20%20%20%20%2045-------------->4.5分
判断数字是两位数就除以10
rating%20=%20item.xpath('./div/div[2]/div[2]/div/span[1]/@class')[0]
%20%20%20%20%20%20%20%20rating%20=%20re.findall('rating(.*?)-t',%20rating)[0]
%20%20%20%20%20%20%20%20if%20len(rating)%20==%202:
%20%20%20%20%20%20%20%20%20%20%20%20star%20=%20int(rating)%20/%2010%20%20#int()转化为数字
%20%20%20%20%20%20%20%20else:
%20%20%20%20%20%20%20%20%20%20%20%20star%20=%20rating
4.4%20正则表达式匹配数字
import%20re%20
data%20=%20"1059232人评价"
num%20=%20re.sub(r'\D',%20"",%20data)
print(%20num)
结果为:
1059232
5.提取第一页所有信息
我们通过上面的%20xpath%20只能提取到一条信息,如果我们要提取所有的信息,就需要写一个%20for%20循环把它遍历出来。先复制几个电影名字的%20xpath来分析一下,如前三个的:
li%20标签前的作为父级,后面的为子集,用./%20代替父级的位置,改写为:
li%20=%20html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li')
for%20item%20in%20li:
%20%20%20%20name%20=%20item.xpath('./div/div[2]/div[1]/a/span[1]/text()')[0]
%20%20%20%20print%20(name)
本页结果为:
肖申克的救赎
霸王别姬
阿甘正传
这个杀手不太冷
美丽人生
泰坦尼克号
千与千寻
辛德勒的名单
盗梦空间
忠犬八公的故事
海上钢琴师
三傻大闹宝莱坞
楚门的世界
机器人总动员
放牛班的春天
星际穿越
大话西游之大圣娶亲
熔炉
疯狂动物城
无间道
龙猫
教父
当幸福来敲门
怦然心动
触不可及
6.将爬取内容写入CSV文件
步骤:
打开文件夹 放进文件夹 关闭文件夹#导入包
import%20csv
#%20创建文件夹并打开
fp%20=%20open("./豆瓣top250.csv",%20'a',%20newline='',%20encoding%20=%20'utf-8-sig')
writer%20=%20csv.writer(fp)%20#写入内容
#%20写入内容
writer.writerow(('排名',%20'名称',%20'链接',%20'星级',%20'评分',%20'评价人数'))
#关闭文件
fp.close()
7.代码汇总
import%20requests,%20csv,%20re
from%20lxml%20import%20etree
#设置浏览器代理,它是一个字典
headers%20=%20{
%20%20%20%20'User-Agent':'Mozilla/5.0%20(Windows%20NT%2010.0;%20Win64;%20x64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/80.0.3987.149%20Safari/537.36'
}
#%20创建文件夹并打开
fp%20=%20open("./豆瓣top250.csv",%20'a',%20newline='',%20encoding%20=%20'utf-8-sig')
writer%20=%20csv.writer(fp)%20#我要写入
#%20写入内容
writer.writerow(('排名',%20'名称',%20'链接',%20'星级',%20'评分',%20'评价人数'))
for%20page%20in%20range(0,%20226,%2025):%20#226
%20%20%20%20print%20("正在获取第%s页"%page)
%20%20%20%20url%20=%20'https://movie.douban.com/top250?start=%s&filter='%page
%20%20%20%20
%20%20%20%20#请求源代码,向服务器发出请求,200代表成功,回退对其,Ctrl+]
%20%20%20%20reponse%20=%20requests.get(url%20=%20url,%20headers%20=%20headers).text
%20%20%20%20#%20快捷键运行,Ctrl+Enter
%20%20%20%20html_etree%20=%20etree.HTML(reponse)%20#%20看成一个筛子,树状
%20%20%20%20#%20过滤
%20%20%20%20li%20=%20html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li')
%20%20%20%20for%20item%20in%20li:
%20%20%20%20%20%20%20%20#排名
%20%20%20%20%20%20%20%20rank%20=%20item.xpath('./div/div[1]/em/text()')[0]
%20%20%20%20%20%20%20%20#电影名称
%20%20%20%20%20%20%20%20name%20=%20item.xpath('./div/div[2]/div[1]/a/span[1]/text()')[0]
%20%20%20%20%20%20%20%20#链接
%20%20%20%20%20%20%20%20dy_url%20=%20item.xpath('./div/div[2]/div[1]/a/@href')[0]
%20%20%20%20%20%20%20%20#评分
%20%20%20%20%20%20%20%20rating%20=%20item.xpath('./div/div[2]/div[2]/div/span[1]/@class')[0]
%20%20%20%20%20%20%20%20rating%20=%20re.findall('rating(.*?)-t',%20rating)[0]
%20%20%20%20%20%20%20%20if%20len(rating)%20==%202:
%20%20%20%20%20%20%20%20%20%20%20%20star%20=%20int(rating)%20/%2010%20%20#int()转化为数字
%20%20%20%20%20%20%20%20else:
%20%20%20%20%20%20%20%20%20%20%20%20star%20=%20rating
%20%20%20%20#%20%20%20%20%20注释ctrl+?
%20%20%20%20%20%20%20%20rating_num%20=%20item.xpath('./div/div[2]/div[2]/div/span[2]/text()')[0]
%20%20%20%20%20%20%20%20content%20=%20item.xpath('./div/div[2]/div[2]/div/span[4]/text()')[0]
%20%20%20%20%20%20%20%20content%20=%20re.sub(r'\D',%20"",%20content)
#%20%20%20%20%20%20%20%20%20print%20(rank,%20name,%20dy_url,%20star,%20rating_num,%20content)
%20%20%20%20%20%20%20%20#%20写入内容
%20%20%20%20%20%20%20%20writer.writerow((rank,%20name,%20dy_url,%20star,%20rating_num,%20content))
fp.close()
jupyter结果:
正在获取第0页
正在获取第25页
正在获取第50页
正在获取第75页
正在获取第100页
正在获取第125页
正在获取第150页
正在获取第175页
正在获取第200页
正在获取第225页
CSV文件截屏: