python爬虫之通过正则表达式获取豆瓣最新上映电影的海报
0.目录
1.分析页面
2.初步代码
3.代码解释
4.完整代码
5.提高海报质量
6.总结
7.更改后的完整代码
1.分析页面
上两次我们讲了xpath和beautifulsoup获取豆瓣最新上映电影的海报,这一次会使用正则表达式来获取。
xpath获取
BeautifulSoup获取
同样的,干活先看源代码
2.初步代码
这次我们同样是利用< img >标签下的src和alt获得我们想要的信息。
# encoding: utf-8 import requests import re from urllib import request def get_page(url): headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36', 'Referer': 'https://movie.douban.com/', } response = requests.get(url, headers) return response.text def get_img(url): text = get_page(url) # 获取标签<div class="mod-bd">下的所有数据 lis = re.findall(r' <div class="mod-bd">(.*?)</div>', text, re.DOTALL)[0] # 获取src和img urls_img = re.findall(r'<li class="poster">.*?<img.*?src="(.*?)".*?/>', lis, re.DOTALL) names = re.findall(r'<li class="poster">.*?<img.*?alt="(.*?)".*?/>', lis, re.DOTALL) for url_img in urls_img: print(url_img) for name in names: print(name) def main(): url = 'https://movie.douban.com/cinema/nowplaying/guangzhou/' get_img(url) if __name__ == '__main__': main()
展示运行结果的一部分:
3.代码解释
这次使用了标签< div class=“mod-bd” >和< /div >来限制范围,其实我们还可以使用其他的标签。比如< ul class=“lists” >和< /ul >,< div id=“nowplaying” >和< div id=“upcoming” >。唯一要注意的是,正则所做的只是匹配文本,没有所谓的标签范围的匹配。比如之前xpath使用的< div id=“nowplaying” >和< /div >,是因为在HTML里< div >标签开始,必然有< /div >与之对应,而xpath是会对应这一级标签的。但在正则里是不认识这些标签的,而是文本。所以,如果你使用< div id=“nowplaying” >和< /div >,你也只会匹配到下面的内容,即使< div class=“mod-bd” >和< /div >并不处于同一级。
<div id="nowplaying"> <div class="mod-hd"> <h2>正在上映</h2> </div>
4.完整代码
# encoding: utf-8 import requests import re from urllib import request def get_page(url): headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36', 'Referer': 'https://movie.douban.com/', } response = requests.get(url, headers) return response.text def get_img(url): text = get_page(url) # 获取标签<div class="mod-bd">下的所有数据 lis = re.findall(r' <div class="mod-bd">(.*?)</div>', text, re.DOTALL)[0] # 获取src和img urls_img = re.findall(r'<li class="poster">.*?<img.*?src="(.*?)".*?/>', lis, re.DOTALL) names = re.findall(r'<li class="poster">.*?<img.*?alt="(.*?)".*?/>', lis, re.DOTALL) fns_num = 1 num = len(urls_img) for i in range(num): # 下载剧照 request.urlretrieve(urls_img[i], 'images/' + names[i] + '.jpg') # 显示剧照下载的进度 print("\r完成进度: {:.2f}%".format(fns_num * 100 / num), end="") fns_num += 1 def main(): url = 'https://movie.douban.com/cinema/nowplaying/guangzhou/' get_img(url) if __name__ == '__main__': main()
5.提高海报质量
我们通过src所给的url下载的海报仅仅是270x382的图片,不够清晰,作为画质党,我们是有追求的。点进一部电影的介绍页面,然后点击它的海报,再点击下面的查看原图。
会发现这是个1020x1428的图片,这才是我们需要的海报。我们对比一下这两个url。
https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2561172733.webp
https://img3.doubanio.com/view/photo/raw/public/p2561172733.jpg
也就是说我们只需要将之前获得的url里的s_ratio_poster更换成raw就可以获得高质量的海报了。
for i in range(num): key = r'(?<=photo/).+?(?=/public)' new_urls_img = re.sub(key, "raw", urls_img[i]) print(new_urls_img) # 下载剧照 request.urlretrieve(new_urls_img, 'images/' + names[i] + '.jpg')
展示运行结果的一部分:
我们竟然发现程序报错了。点击链接,会发现我们能够打开url,然后刷新一下,会发现竟然变成了403,并且跟我们说没有访问此服务器上URL的权限。
我们查看正常打开的源代码和刷新后的源代码,会发现一个的状态是304,能够访问,一个是403,无法访问。再往下看request headers,会发现正常打开的headers里有referer,并且
https://movie.douban.com/photos/photo/2561172733/
这是我们上一个页面的url,这表明我们在访问原图的url时,服务器会检测你从哪个页面打开这个url的。也就是说,我们想要下载原图,就必须在get的时候添加拥有referer的headers。
从上图,我们可以发现referer中的数字id与之前获得的海报url的数字id相同,也就是豆瓣的电影id与该电影的显示海报的id是绑定的,那我们只需要将之前的url里提取id即可。
def urlretrieve(url, filename=None, reporthook=None, data=None):
之前使用的request.urlretrieve下载方式无法提交headers,也就是说我们需要更换下载方式。
for i in range(num): key = r'(?<=photo/).+?(?=/public)' new_urls_img = re.sub(key, "raw", urls_img[i]) # 下载剧照 id = re.findall(r'.*?/public/p(.*?).jpg', urls_img[i], re.DOTALL) headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36', 'referer': 'https://movie.douban.com/photos/photo/' + str(id) + '/' } r = requests.get(new_urls_img, headers=headers) path = 'D://images//' + names[i] + '.jpg' with open(path, 'wb') as f: f.write(r.content)
展示运行结果的一部分:
6.总结
正则表达式是通过匹配文本来获取信息的,这使得我们在匹配某信息的同时,为了保证信息的准确性还需要添加一个合适的范围。在提高获取的海报的质量时,遇到了各种各样的问题,碰到问题时需要一个个的去克服。比如在下载图片时遇到了豆瓣的一个不算反爬的反爬,可以通过添加referer到headers再去访问就可以顺利解决。python的下载方式是有很多的,针对不同的需求可以使用不同的下载方式。
7.更改后的完整代码
# encoding: utf-8 import requests import re def get_page(url): headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36', 'Referer': 'https://movie.douban.com/', } response = requests.get(url, headers) return response.text def get_img(url): text = get_page(url) # 获取标签<div class="mod-bd">下的所有数据 lis = re.findall(r' <div class="mod-bd">(.*?)</div>', text, re.DOTALL)[0] # 获取src和img urls_img = re.findall(r'<li class="poster">.*?<img.*?src="(.*?)".*?/>', lis, re.DOTALL) names = re.findall(r'<li class="poster">.*?<img.*?alt="(.*?)".*?/>', lis, re.DOTALL) fns_num = 1 num = len(urls_img) for i in range(num): key = r'(?<=photo/).+?(?=/public)' new_urls_img = re.sub(key, "raw", urls_img[i]) # 下载剧照 id = re.findall(r'.*?/public/p(.*?).jpg', urls_img[i], re.DOTALL) headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36', 'referer': 'https://movie.douban.com/photos/photo/' + str(id) + '/' } r = requests.get(new_urls_img, headers=headers) path = 'D://images//' + names[i] + '.jpg' with open(path, 'wb') as f: f.write(r.content) # 显示剧照下载的进度 print("\r完成进度: {:.2f}%".format(fns_num * 100 / num), end="") fns_num += 1 def main(): url = 'https://movie.douban.com/cinema/nowplaying/guangzhou/' get_img(url) if __name__ == '__main__': main()
- Python 网络爬虫 009 (编程) 通过正则表达式来获取一个网页中的所有的URL链接,并下载这些URL链接的源代码
- Python 网络爬虫 009 (编程) 通过正则表达式来获取一个网页中的所有的URL链接,并下载这些URL链接的源代码
- Python爬虫入门——2. 4 利用正则表达式爬取豆瓣电影 Top 250
- Python学习笔记 第二部分 - 正则表达式 与 爬虫小实例(抓取豆瓣电影中评分大于等于8分的影片)
- python3爬虫实战一: 爬取豆瓣最新上映电影及画出词云分布
- Python 爬虫实战:分析豆瓣中最新电影的影评(词云显示)
- Python爬虫之模拟登录豆瓣获取最近看过的电影
- Python通过正则表达式和字符串处理获取方式获取所需子字符串的方式
- 基础爬虫,谁学谁会,用requests、正则表达式爬取豆瓣Top250电影数据!
- 爬虫实战【11】Python获取豆瓣热门电影信息
- Python网络爬虫:利用正则表达式爬取豆瓣电影top250排行前10页电影信息
- python爬虫—豆瓣电影海报(按类别)
- python爬虫实战:分析豆瓣中最新电影的影评
- Python爬虫获取豆瓣电影TOP250
- Python 爬虫实战:分析豆瓣中最新电影的影评
- Python 爬虫实战(1):分析豆瓣中最新电影的影评并制作词云
- Python通过正则表达式获取,去除(过滤)或者替换HTML标签的几种方法(本文由169it.com搜集整理)
- python爬虫获取豆瓣正在热播电影
- python3爬虫之入门和正则表达式,获取IP地址, 隐马尔可夫模型及其在分词中的简单应用
- python 爬虫 保存豆瓣TOP250电影海报及修改名称