手把手教你爬取豆瓣Top250

最近在家看了些关于爬虫的资料,发一个小项目给想学爬虫的人带个路~尽可能地介绍一下每步的理由和做法。关于爬虫的资料太多了,初学者很容易迷失在各种各样的框架、库中(比如博主),也是借这个小项目给大家理一下爬虫的学习路程!
一般而言,其实爬虫就是三个步骤:(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的

    下面有一串的
  1. 标签,每个
  2. 标签即为一个电影。
    在这里插入图片描述

    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="">1em><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 Redemptionspan><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.7span><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:可以看到标签的alt属性即为电影名
    img:可以看到标签的src属性即为图片地址
    rating:可以看到class属性为star的标签下的class属性为rating_num的中的文字内容即为评分

    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] #图片urlrating = 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 += 1for 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=(',', ':')))
    

    结果截图:
    在这里插入图片描述
    在这里插入图片描述


    本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部