当前位置:   article > 正文

手把手教你爬取豆瓣Top250_site:csdn.net 为什么爬取的top250只有25条数据

site:csdn.net 为什么爬取的top250只有25条数据

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

有一点需要说明,为什么是发送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代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

得到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">&nbsp;/&nbsp;The Shawshank Redemption</span>
                                <span class="other">&nbsp;/&nbsp;月黑高飞(港)  /  刺激1995(台)</span>
                        </a>


                            <span class="playable">[可播放]</span>
                    </div>
                    <div class="bd">
                        <p class="">
                            导演: 弗兰克·德拉邦特 Frank Darabont&nbsp;&nbsp;&nbsp;主演: 蒂姆·罗宾斯 Tim Robbins /...<br>
                            1994&nbsp;/&nbsp;美国&nbsp;/&nbsp;犯罪 剧情
                        </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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

继续分析,这里取三种数据为例
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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

运行结果
在这里插入图片描述

数据存储

电影的图片下载到文件夹,其他的数据存储到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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

完整代码

以上完成了肖申克的救赎的信息存储和图片存储,其他电影的同理,只需要增加一些循环即可。
另外我们爬取的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=(',', ':')))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/191233
推荐阅读
相关标签
  

闽ICP备14008679号