ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

爬虫实战(五):爬豆瓣top250

2022-07-06 13:00:09  阅读:222  来源: 互联网

标签:__ xpath ol douban data 爬虫 li 豆瓣 top250


目录

爬虫实战(五):爬豆瓣top250

一、网址分析

1、 页面分析

通过抓包分析,可得数据不是动态加载出来的,而是静态页面,故我们可以直接发送请求到页面,就可以获得数据了

2、 源码分析

通过F12调试工具可以得到页面数据,即,该页面的数据,存储在一个类名为grid_view的ol标签里面,同时该类名在页面中唯一,故我们可以使用这个节点定位到我们的数据,遍历li标签,获取内容

3、 内容解析

4、 链接分析

"""
1. https://movie.douban.com/top250?start=0
2. https://movie.douban.com/top250?start=25
3. https://movie.douban.com/top250?start=50
n. https://movie.douban.com/top250?start=25*(n-1)
"""
urls = [https://movie.douban.com/top250?start=25*(i-1) for i in range(11)]  # 其总共有250部电影

故,我们可以使用for循环,或者是先生成链接,采用入栈的形式来访问,亦或者可以使用递归的方式来爬取页面

二、编写代码

1、 获取每页url

# !/usr/bin/python3
# -*- coding: UTF-8 -*-
__author__ = "A.L.Kun"
__file__ = "123.py"
__time__ = "2022/7/6 10:19"

import requests, re  # 导入模块
from lxml import etree  # 进行xpath解析
from fake_useragent import UserAgent  # 使用随机请求头
import pandas as pd  # 导入数据解析模快

urls = [f'https://movie.douban.com/top250?start={25*(i-1)}' for i in range(10, 0, -1)]  # 获取全部的url链接,存储为全局变量,使用出栈的方式,所以采取倒序

headers = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
    'Host': 'movie.douban.com',
    'Pragma': 'no-cache',
    'sec-ch-ua': '"Not A;Brand";v="99", "Chromium";v="102", "Google Chrome";v="102"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Windows"',
    'Sec-Fetch-Dest': 'document',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-Site': 'none',
    'Sec-Fetch-User': '?1',
    'Upgrade-Insecure-Requests': '1',
    'user-agent': UserAgent().random
}

lis_data = []  # 存储爬取到的数据

while urls:
    print(urls.pop())

2、 获取ol里面的li标签

def get_tags(url):
    headers.update({'user-agent': UserAgent().random})  # 使得user-agent足够随机
    resp = requests.get(url, headers=headers)  # 发送请求
    resp.encoding = "utf-8"  # 设置编码
    tree = etree.HTML(resp.text)  # 得到页面源码,交给etree
    ol = tree.xpath('//*[@id="content"]/div/div[1]/ol/li')  # 获取到ol
    for li in ol:  
        print(li)
    
get_tags("https://movie.douban.com/top250?start=0")

3、 获取数据

def get_data(li):
    imgSrc = li.xpath(".//img/@src")[0]  # 图片链接
    try:
        imgSrc = imgSrc.replace("webp", "jpg")
    except Exception as e:
        imgSrc = "图片没有找到"
    title = li.xpath(".//img/@alt")[0]  # 标题
    detailUrl = li.xpath(".//div[@class='hd']/a/@href")[0]  # 详细地址
    detail = li.xpath(".//div[@class='bd']/p[1]/text()")  # 里面包含导演,年份,类型,我们只要年份和类型
    time = re.search(r"\d+", detail[1]).group()  # 出版年份
    type_ = " ".join(re.findall(r"[\u4e00-\u9fa5]+", detail[1]))  # 电影类型
    score = li.xpath(".//span[@class='rating_num']/text()")[0]  # 获取评分
    quote = li.xpath(".//span[@class='inq']/text()")[0]  # 电影格言
    # print(title, imgSrc, detailUrl, time, type_, score, quote)  # 输出获取的数据
    lis_data.append({
        "标题": title,
        "图片链接": imgSrc,
        "详情页链接": detailUrl,
        "出版时间": time,
        "电影类型": type_,
        "评分": score,
        "格言": quote
    })  # 把结果存储到准备好的容器中,提交给pandas库进行解析,这里也可以将数据写入数据库
    

# 测试使用
resp = requests.get("https://movie.douban.com/top250?start=25", headers=headers)
resp.encoding = "utf-8"
tree = etree.HTML(resp.text)  # 得到页面源码,交给etree
ol = tree.xpath('//*[@id="content"]/div/div[1]/ol/li')  # 获取到ol
for li in ol :
    get_data(li)
print(lis_data)

4、 数据清洗

def parse_data():
    df = pd.DataFrame(lis_data)
    new_df = df.dropna()  # 可以,丢弃为空的数据
    # 同时也还可以做一些图表分析等工作,这里就省略
    # print(new_df)
    new_df.to_excel("./douban.xlsx", index=None)

parse_data()

三、完整代码

# !/usr/bin/python3
# -*- coding: UTF-8 -*-
__author__ = "A.L.Kun"
__file__ = "123.py"
__time__ = "2022/7/6 10:19"

import requests, re  # 导入模块
from lxml import etree  # 进行xpath解析
from fake_useragent import UserAgent  # 使用随机请求头
import pandas as pd  # 导入数据解析模快
from logging import Logger

log = Logger(__name__)

urls = [f'https://movie.douban.com/top250?start={25*(i-1)}' for i in range(10, 0, -1)]  # 获取全部的url链接,存储为全局变量,使用出栈的方式,所以采取倒序

headers = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
    'Host': 'movie.douban.com',
    'Pragma': 'no-cache',
    'sec-ch-ua': '"Not A;Brand";v="99", "Chromium";v="102", "Google Chrome";v="102"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Windows"',
    'Sec-Fetch-Dest': 'document',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-Site': 'none',
    'Sec-Fetch-User': '?1',
    'Upgrade-Insecure-Requests': '1',
    'user-agent': UserAgent().random
}

lis_data = []  # 存储爬取到的数据

def get_data(li):
    imgSrc = li.xpath(".//img/@src")[0]  # 图片链接
    try:
        imgSrc = imgSrc.replace("webp", "jpg")
    except Exception as e:
        imgSrc = "图片没有找到"
    title = li.xpath(".//img/@alt")[0]  # 标题
    detailUrl = li.xpath(".//div[@class='hd']/a/@href")[0]  # 详细地址
    detail = li.xpath(".//div[@class='bd']/p[1]/text()")  # 里面包含导演,年份,类型,我们只要年份和类型
    time = re.search(r"\d+", detail[1]).group()  # 出版年份
    type_ = " ".join(re.findall(r"[\u4e00-\u9fa5]+", detail[1]))  # 电影类型
    score = li.xpath(".//span[@class='rating_num']/text()")[0]  # 获取评分
    try:
        quote = li.xpath(".//span[@class='inq']/text()")[0]  # 电影格言
    except Exception as e:
        quote = "暂时没有格言哦!"
    # print(title, imgSrc, detailUrl, time, type_, score, quote)  # 输出获取的数据
    lis_data.append({
        "标题": title,
        "图片链接": imgSrc,
        "详情页链接": detailUrl,
        "出版时间": time,
        "电影类型": type_,
        "评分": score,
        "格言": quote
    })  # 把结果存储到准备好的容器中,提交给pandas库进行解析,这里也可以将数据写入数据库

def get_tags(url):
    headers.update({'user-agent': UserAgent().random})  # 使得user-agent足够随机
    resp = requests.get(url, headers=headers)  # 发送请求
    resp.encoding = "utf-8"  # 设置编码
    tree = etree.HTML(resp.text)  # 得到页面源码,交给etree
    ol = tree.xpath('//*[@id="content"]/div/div[1]/ol/li')  # 获取到ol
    for li in ol:  
        get_data(li)  # 获取到数据
    log.info(f"{url},数据获取完成")

def parse_data():
    df = pd.DataFrame(lis_data)
    new_df = df.dropna()  # 可以,丢弃为空的数据
    # 同时也还可以做一些图表分析等工作,这里就省略
    # print(new_df)
    new_df.to_excel("./douban.xlsx", index=None, encoding="utf-8")
    # print(new_df)

def main():
    while urls:
        get_tags(urls.pop())
    parse_data()

if __name__ == "__main__":
    main()

标签:__,xpath,ol,douban,data,爬虫,li,豆瓣,top250
来源: https://www.cnblogs.com/liuzhongkun/p/16450367.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有