Python爬虫入门 ~ 电影数据爬取案例

1,856 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第16天,点击查看活动详情

电影数据爬取案例

前面我们已经学过了如何发起请求,getpost方式都有简单的案例。那么我们现在就以某瓣电影来继续深入学习吧!

1.定位接口

我们打开动作分类的电影页面,可以看到有一部部的电影信息展示出来,按F12打开浏览器开发调试工具页面,选中Network标签页,选择XHR类型,过滤掉一些静态资源类的请求,这样我们可以更容易找到所需要的数据。在剩下的几个请求中一个个点击查看是否为我们所需的数据。

image.png

2.发起请求,获取响应

找到请求路径之后,我们先以前面所学的方式,定制一个请求对象,发出请求看看能不能拿到所需要的数据。

# 动作类电影第一页数据

import urllib.request

url = 'https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&start=0&limit=20'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.116 Safari/537.36',
}

# 1. 定制请求对象
request = urllib.request.Request(url=url, headers=headers)

# 2. 获取响应数据
response = urllib.request.urlopen(request)
result = response.read().decode('utf-8')
print(result)

image.png

3. 保存数据

拿到数据之后,我们就可以将其先保存起来,留待后续使用了。调用open()函数,将请求到的结果写入movies.json中,需要注意的是,请求回来的数据是json格式的,所以我们创建的文件后缀名也要用json类型,同时由于响应中有中文的存在,我们还需指定文件的编码类型encoding='utf-8'

movies = open('movies.json', 'w', encoding='utf-8')
movies.write(result)

image.png

4. 自动翻页

首页的前20条数据我们已经拿到了,但是它可远远不止20条数据,当我们向下滚动的时候,它还会继续刷新出新的页面来,在开发调试工具栏中还可以看到有一条新的请求发出

image.png

将请求地址复制下来,与前面的做一下对比:

url = 'https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&start=0&limit=20'
#      https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&start=20&limit=20

可以看出,只有start参数发生了变化,其它参数并没有任何改变。知道了它是使用哪个参数来控制翻页的之后,我们就可以实现自动翻页的效果了,这次让我们来试试看能不能将前10页的数据都抓取保存下来吧。

步骤:

  1. 将原先的请求路径拆分,把start参数抽取出来定义成变量
  2. 使用for循环来实现翻页功能
  3. 发出请求
  4. 将获取到的响应写入文件中,记得需要采用a模式追加写入
# 动作类电影前十页数据

import urllib.request

url = 'https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&start='
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.116 Safari/537.36',
}

for page in range(0, 20 * 10, 20):
    # 1. 定制请求对象
    request = urllib.request.Request(url=url + str(page) + '&limit=20', headers=headers)

    # 2. 获取响应数据
    response = urllib.request.urlopen(request)
    result = response.read().decode('utf-8')
    print(result)

    # 3. 保存数据
    movies = open('movies.json', 'a', encoding='utf-8')
    movies.write(result + '\n')

image.png

4. 程序优化

上面的代码虽然效果能实现,但是全部都对方在一起了,这样看着会比较乱,不够规范,我们可以将一些重复使用的逻辑抽取成一个个的函数,通过函数来进行调用,具体步骤如下:

  1. 定义一个创建请求对象的函数
  2. 定义一个获取响应结果的函数
  3. 定义一个下载并保存数据的函数
# 动作类电影数据
import urllib.request
import urllib.parse

# 定制请求对象
def create_request(page):
    base_url = 'https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action='
    data = urllib.parse.urlencode({
        'start': (page - 1) * 20,
        'limit': 20
    })
    url = base_url + data
    print(url)
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.116 Safari/537.36',
    }
    return urllib.request.Request(url=url, headers=headers)

# 获取响应数据
def getResponseData(request):
    response = urllib.request.urlopen(request)
    return response.read().decode('utf-8')


# 下载数据
def download(list):
    movies = open('movies.json', 'a', encoding='utf-8')
    movies.write(list)

if __name__ == '__main__':
    startPage = int(input('请输入起始页:'))
    endPage = int(input('请输入结束页:'))

    for page in range(startPage, endPage + 1):
        request = create_request(page)
        list = getResponseData(request)
        download(list)

image.png

效果图中可以看出,我们将需要获取的页数调整为手动选择的了,这样就不需要每次都去调整代码,控制台打印出来的数据也可以看出发出的请求路径都是正确的。