赞
踩
最近在家看了些关于爬虫的资料,发一个小项目给想学爬虫的人带个路~尽可能地介绍一下每步的理由和做法。关于爬虫的资料太多了,初学者很容易迷失在各种各样的框架、库中(比如博主),也是借这个小项目给大家理一下爬虫的学习路程!
一般而言,其实爬虫就是三个步骤:(1)网页爬取(2)数据解析(3)数据存储
网页爬取: 获取你需要的网页的HTML代码(这部分需要注意一下反爬虫机制),常用的库有:urllib或者requests,二者选其一即可
数据解析: 从获取的HTML代码中得到自己想要的数据,常用的库:lxml(xpath语法)或者beautifulSoup4或者re(正则),三者最好都要学,初学者可以从beautifulSoup4开始学。在我看来,数据解析是整个爬虫的精华也是难点。
数据存储: 很容易理解,即把解析到的数据存储为自己想要的格式。
使用requests库
按下F12,进入开发者模式,选中Network,然后刷新,可以看到一个数据包,选中,查看其Headers。豆瓣的对爬虫很友好,我们的headers中只需要伪装两项:Referer和User-Agent,将浏览器中的复制下来即可!
import requests
#设置Headers值
headers = {
'User-Agent': "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/80.0.3987.116 Mobile Safari/537.36",
'Referer': 'https://movie.douban.com/top250'
}
url = 'https://movie.douban.com/top250' #url值
response = requests.get(url, headers=headers) #使用requests库发送get请求
text = response.text #获取html代码
#存储得到的html代码
with open('./html.txt', 'w', encoding='utf-8') as f:
f.write(text)
有一点需要说明,为什么是发送get请求,也是在NetWork-Headers中得知的,一般而言,常用的是get和post请求。
我们可以得到html.txt如下:
使用lxml库
首先先对HTML代码分析,同样是在开发者模式下,定位到整个需要爬取的页面,可以看到在class = grid_view的<ol>下面有一串的<li>标签,每个<li>标签即为一个电影。
from lxml import etree import requests #设置Headers值 headers = { 'User-Agent': "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 " "(KHTML, like Gecko) Chrome/80.0.3987.116 Mobile Safari/537.36", 'Referer': 'https://movie.douban.com/top250' } url = 'https://movie.douban.com/top250' #url值 response = requests.get(url, headers=headers) #使用requests库发送get请求 text = response.text #获取html代码 #存储得到的html代码 with open('./html.txt', 'w', encoding='utf-8') as f: f.write(text) html = etree.HTML(text) ul = html.xpath("//ol[@class='grid_view']")[0] #查找class为grid_view的ol标签,返回的是列表,所以取第0项去除列表 movie = ul.xpath("./li")[0] #查找该ol标签下的li标签,这里取第一项 print(etree.tostring(movie, encoding='utf-8').decode('utf-8')) #打印li标签中的HTML代码
得到HTML代码如下:
<li> <div class="item"> <div class="pic"> <em class="">1</em> <a href="https://movie.douban.com/subject/1292052/"> <img width="100" alt="肖申克的救赎" src="https://img3.doubanio.com/view/photo/s_ratio_poster/public/p480747492.jpg" class=""> </a> </div> <div class="info"> <div class="hd"> <a href="https://movie.douban.com/subject/1292052/" class=""> <span class="title">肖申克的救赎</span> <span class="title"> / The Shawshank Redemption</span> <span class="other"> / 月黑高飞(港) / 刺激1995(台)</span> </a> <span class="playable">[可播放]</span> </div> <div class="bd"> <p class=""> 导演: 弗兰克·德拉邦特 Frank Darabont 主演: 蒂姆·罗宾斯 Tim Robbins /...<br> 1994 / 美国 / 犯罪 剧情 </p> <div class="star"> <span class="rating5-t"></span> <span class="rating_num" property="v:average">9.7</span> <span property="v:best" content="10.0"></span> <span>1857327人评价</span> </div> <p class="quote"> <span class="inq">希望让人自由。</span> </p> </div> </div> </div> </li> <li>
继续分析,这里取三种数据为例
title:可以看到<img>标签的alt属性即为电影名
img:可以看到<img>标签的src属性即为图片地址
rating:可以看到class属性为star的<div>标签下的class属性为rating_num的<span>中的文字内容即为评分
from lxml import etree import requests #设置Headers值 headers = { 'User-Agent': "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 " "(KHTML, like Gecko) Chrome/80.0.3987.116 Mobile Safari/537.36", 'Referer': 'https://movie.douban.com/top250' } url = 'https://movie.douban.com/top250' #url值 response = requests.get(url, headers=headers) #使用requests库发送get请求 text = response.text #获取html代码 #存储得到的html代码 with open('./html.txt', 'w', encoding='utf-8') as f: f.write(text) html = etree.HTML(text) ul = html.xpath("//ol[@class='grid_view']")[0] #查找class为grid_view的ol标签,返回的是列表,所以取第0项去除列表 movie = ul.xpath("./li")[0] #查找该ol标签下的li标签,这里取第一项 title = movie.xpath(".//img/@alt")[0] img = movie.xpath(".//img/@src")[0] rating = movie.xpath(".//div[@class='star']/span[@class='rating_num']/text()")[0] print("名称:", title, "\n图片: ", img, "\n评分:", rating)
运行结果
电影的图片下载到文件夹,其他的数据存储到json文件中,这里还是用肖申克的救赎为例。
import json from lxml import etree import requests #设置Headers值 headers = { 'User-Agent': "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 " "(KHTML, like Gecko) Chrome/80.0.3987.116 Mobile Safari/537.36", 'Referer': 'https://movie.douban.com/top250' } url = 'https://movie.douban.com/top250' #url值 response = requests.get(url, headers=headers) #使用requests库发送get请求 text = response.text #获取html代码 #存储得到的html代码 with open('./html.txt', 'w', encoding='utf-8') as f: f.write(text) html = etree.HTML(text) ul = html.xpath("//ol[@class='grid_view']")[0] #查找class为grid_view的ol标签,返回的是列表,所以取第0项去除列表 movie = ul.xpath("./li")[0] #查找该ol标签下的li标签,这里取第一项 title = movie.xpath(".//img/@alt")[0] #名称 img = movie.xpath(".//img/@src")[0] #图片url rating = movie.xpath(".//div[@class='star']/span[@class='rating_num']/text()")[0] #评分 movieUrl = movie.xpath(".//a/@href")[0] #电影链接 quote = movie.xpath(".//span[@class='inq']/text()")[0] #语录 info = {"名称": title, "评分": rating, "链接": movieUrl, "语录": quote} #信息存储为字典 #信息保存到json文件 with open('movieTop250.json', 'w', encoding='utf-8') as f: f.write(json.dumps(info, ensure_ascii=False, indent=4, separators=(',', ':'))) #保存图片 with requests.get(img, stream=True, headers=headers) as resp: with open('./img/1.jpg', 'wb') as fd: for chunk in resp.iter_content(): fd.write(chunk)
以上完成了肖申克的救赎的信息存储和图片存储,其他电影的同理,只需要增加一些循环即可。
另外我们爬取的https://movie.douban.com/top250只有25个电影,其他还有9个页面,点下一个页面的url为https://movie.douban.com/top250?start=25&filter=,可以发现规律,每次start递进25。
整理一下代码:
import requests from lxml import etree import json #设置Headers值 headers = { 'User-Agent': "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 " "(KHTML, like Gecko) Chrome/80.0.3987.116 Mobile Safari/537.36", 'Referer': 'https://movie.douban.com/top250' } cnt = 1 infos = [] for i in range(0, 250, 25): url = 'https://movie.douban.com/top250?start='+str(i)+'&filter=' # url值 response = requests.get(url, headers=headers) #使用requests库发送post请求 text = response.text #获取html代码 #存储得到的html代码 # with open('./html.txt', 'w', encoding='utf-8') as f: # f.write(text) html = etree.HTML(text) ul = html.xpath("//ol[@class='grid_view']")[0] #查找class为grid_view的ol标签,返回的是列表,所以取第0项去除列表 movies = ul.xpath("./li") #查找该ol标签下的li标签,这里取第一项 # print(etree.tostring(movies, encoding='utf-8').decode('utf-8')) #打印li标签中的HTML代码 for movie in movies: title = movie.xpath(".//img/@alt")[0] #名称 img = movie.xpath(".//img/@src")[0] #图片url rating = movie.xpath(".//div[@class='star']/span[@class='rating_num']/text()")[0] #评分 movieUrl = movie.xpath(".//a/@href")[0] #电影链接 quote = movie.xpath(".//span[@class='inq']/text()") #语录 quote = " " if not quote else quote[0] info = {"名称": title, "排名": cnt, "评分": rating, "链接": movieUrl, "语录": quote} #信息存储为字典 infos.append(info) #保存图片 with requests.get(img, stream=True, headers=headers) as resp: with open('./img/'+str(cnt)+'.jpg', 'wb') as fd: cnt += 1 for chunk in resp.iter_content(): fd.write(chunk) #信息保存到json文件 with open('movieTop250.json', 'w', encoding='utf-8') as f: f.write(json.dumps(infos, ensure_ascii=False, indent=4, separators=(',', ':')))
结果截图:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。