使用python3爬取豆瓣电影top250

经过一个多星期的学习,对python3的语法有了一定了解,马上动手做了一个爬虫,检验学习效果

目标

  • 爬取豆瓣电影top250中每一部电影的名称、排名、链接、名言、评分

准备工作

  • 运行平台:windows10
  • IDE:PyCharm
  • requests、BeautifulSoup库(使用pip进行安装)

第一步:向服务器发送请求,获得响应

由于豆瓣电影top250上信息均在html源码中,故需获取其源码,使用requests库。代码如下:

import requests


def get_html(url):
    response = requests.get(url)  # 发送get请求
    if response.status_code == 200:  # 如果服务器响应成功,返回网页源代码
        return response.text
    else:
        print("访问失败")

第二步:对源码进行解析,提取

  1. 单页分析

    • 首先分析原网页代码:
      在这里插入图片描述
      发现我们所需要的信息都在 li 标签中,所以我们需要定位在li标签中提取信息
      但是,我们又发现:在真正含有我们所需要的信息的li 标签前,还有19个不含我们所需信息的li标签:
      在这里插入图片描述
      在这里插入图片描述
      所以,在提取信息的时候需要将前19个 li 标签排除在外
      再对含有我们所需内容的 li 标签进行分析:
      在这里插入图片描述
      可以看到:影片名为<span class="title"标签的文本内容;排名为<em的文本内容;链接是<a 标签中href属性对应的值;名言为标签<span class=“inq” 的文本内容;评分为<span class=“rating_num” property=“v:average” 的文本内容;
      利用这些信息就可以利用find()函数定位信息,进行提取

    代码如下:

    from bs4 import BeautifulSoup
    
    
    def parse_html(html):
    soup = BeautifulSoup(html, 'lxml') # 创建BeautifulSoup对象,使用lxml解析库
    items = soup.find_all(name='li')  # 查询名称为li的元素,以列表形式输出
    for item in items[19:]:
    # 注意这里的[19:],对网页源码分析后发现前19个li标签中并没有我们需要的数据,所以将其排除在外
        yield {
            # 利用find()函数定位我们需要的数据,并作为生成器元素
            'title': item.span.get_text(),    # 影片名
            'index': item.find(name='em').text,   # 影片排名
            'image': item.find(name='a')['href'],		# 影片链接
            'quote': item.find(class_="inq").text,	# 影片名言
            'score': item.find(class_="rating_num").text	# 影片评分
        }  
        # 构造生成器,作为函数的返回结果
        # 获取Tag对象的文本信息有三种方法,.string、.text、.get_text()
    

    以上完成了对豆瓣电影一页源代码的解析,接下来进行多页的解析,将250部电影的信息全部爬取下来:

多页爬取

在换页的时候,我们发现网页的URL发生了改变:

	第二页的URL:https://movie.douban.com/top250?start=25&filter=
	第三页的URL:https://movie.douban.com/top250?start=50&filter=

我们发现,每跳一页,URL中参数start的值就增加25,所以可将start作为偏移量,来定位每一页网址.
代码如下:

# 解析源码
def main(start):
	url = 'https://movie.douban.com/top250?start=' + str(start) + '&filter'  # 定位top250的url
    html = get_html(url)  # 获取源码
    for item in parse_html(html):
        print(item)
 
 if __name__ == '__main__':
 	for page in range(10):
 		main(page * 25)   # 遍历10页,250部电影

将爬取到的信息写入txt文件:

定义如下函数,实现将数据写入txt文件的操作

def write_to_file(content):
    with open("movies.txt", 'a', encoding='utf-8') as file:  # 以追加的权限打开文件movies.txt
        file.write(json.dumps(content, ensure_ascii=False) + '\n')  # ensure_ascii设为False,保证输出是中文形式,而不是ASCII编码
        # json.dumps()序列化时默认对中文使用ascii编码

这样就实现了豆瓣电影top250的爬取;

全部代码:

# 爬取豆瓣top250
import requests
import json
from bs4 import BeautifulSoup


# 获取源码
def get_html(url):
    response = requests.get(url)
    if response.status_code == 200:
        return response.text
    else:
        print("访问失败")


# 解析源码
def parse_html(html):
    soup = BeautifulSoup(html, 'lxml') # 创建BeautifulSoup对象,使用lxml解析库
    items = soup.find_all(name='li')  # 查询名称为li的元素,以列表形式输出
    for item in items[19:]:
    # 注意这里的[19:],对网页源码分析后发现前19个li标签中并没有我们需要的数据,所以将其排除在外
        yield {
            # 利用find()定位我们需要的数据,并作为生成器元素
            'title': item.span.get_text(),
            'index': item.find(name='em').text,
            'image': item.find(name='a')['href'],
            'quote': item.find(class_="inq").text,
            'score': item.find(class_="rating_num").text
        }
        # 构造生成器,作为函数的返回结果


# 将数据转化为json字符串并写入到文件中
def write_to_file(content):
    with open("movies.txt", 'a', encoding='utf-8') as file:  # 以追加的权限打开文件movies.txt
        file.write(json.dumps(content, ensure_ascii=False) + '\n')  # ensure_ascii设为False,保证输出是中文形式,而不是ASCII编码
        # json.dumps()序列化时默认对中文使用ascii编码


def main(start):
    url = 'https://movie.douban.com/top250?start=' + str(start) + '&filter'  # 定位top250的url
    html = get_html(url)
    for item in parse_html(html):
        print(item)
        write_to_file(item)


# 执行函数,完成爬取
if __name__ == '__main__':
    for i in range(10):
        main(i * 25)

从中的感觉就是,基本的语法、函数的使用是比较简单的;关键之处在于对网页源码的分析,找到合适的提取信息的方式。

猜你喜欢

转载自blog.csdn.net/qq_43271202/article/details/82830855