python-爬虫-豆瓣电影TOP250

236 阅读3分钟

记录学习爬虫 爬取OP250的数据

步骤
  • 拿到网页源代码
    • 使用requests模块
    • 找到url movie.douban.com/top250
    • 模拟浏览器请求头User-Agent
    • 这里涉及到一个概念 服务器渲染 服务器直接返回HTML渲染在前端页面 所以要通过re模块来匹配 拿到需要的数据
    • 代码如下
import requests
import re
import csv

url = 'https://movie.douban.com/top250'
param = {
    "start": num
}
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
}
# headers的作用是模拟浏览器的环境 不然豆瓣的反爬会检测到 导致失败
resp = requests.get(url, headers=headers)
# 页面源代码
page_content = resp.text
# 此时可以输出看看拿到的值 是不是正确的
print(page_content)
  • 通过re模块来匹配 拿到需要的数据
    • 通过查看网络源代码 找到需要从哪里开始匹配 这里我是从li开始匹配
    • 具体的在代码的注释上写了 直接上代码
# 解析数据
# r'' 的作用是去除转义字符
# 输出的格式为: 1,肖申克的救赎,1994,9.7,2682252人评价
# 从<li>开始匹配 一直匹配到<em class="">的位置 使用分组 找到序号 遇到</em>结束
# 接着继续找名字 从</em> 一直匹配到<span class="title">的位置 使用分组 找到名字 遇到</span>结束
# 重复以上步骤 找到想要拿到的数据

obj = re.compile(r'<li>.*?<em class="">(?P<index>.*?)</em>'
                 r'.*?<span class="title">(?P<name>.*?)</span>'
                 r'.*?<p class="">.*?<br>(?P<year>.*?)&nbsp'
                 r'.*?<span class="rating_num" property="v:average">(?P<scope>.*?)</span>'
                 r'.*?<span>(?P<count>.*?)</span>', re.S)
# re模块中的re.S   使 . 匹配包括换行在内的所有字符
result = obj.finditer(page_content)

image.png

  • 拿到了需要的数据 保存在文件中
    • 一次只能拿25条数据 所以我们需要写一个循环来拿完全部的250条数据
    • 使用open方法写入到文件中
    • 到此 第一个爬虫demo就结束了
  • 源代码
import requests
import re
import csv
# 拿到页面源代码
# 通过re提取有效信息

def get_douban_list(num):
    url = 'https://movie.douban.com/top250'
    # print(num)
    param = {
        "start": num
    }
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
    }
    # headers的作用是模拟浏览器的环境 不然豆瓣的反爬会检测到 导致失败
    resp = requests.get(url, params=param, headers=headers)
    # 页面源代码
    page_content = resp.text

    # 解析数据
    # r'' 的作用是去除转义字符
    # 输出的格式为: 1,肖申克的救赎,1994,9.7,2682252人评价
    # 从<li>开始匹配 一直匹配到<em class="">的位置 使用分组 找到序号 遇到</em>结束
    # 接着继续找名字 从</em> 一直匹配到<span class="title">的位置 使用分组 找到名字 遇到</span>结束
    # 重复以上步骤 找到想要拿到的数据

    obj = re.compile(r'<li>.*?<em class="">(?P<index>.*?)</em>'
                     r'.*?<span class="title">(?P<name>.*?)</span>'
                     r'.*?<p class="">.*?<br>(?P<year>.*?)&nbsp'
                     r'.*?<span class="rating_num" property="v:average">(?P<scope>.*?)</span>'
                     r'.*?<span>(?P<count>.*?)</span>', re.S)
    # re模块中的re.S   使 . 匹配包括换行在内的所有字符
    result = obj.finditer(page_content)
    # 1.data.csv 要保存的文件名
    # 2.mode = 'a' a代表往文件中继续添加数据 而不是覆盖原本的数据
    # 3.encoding='utf-8' 编码转为utf-8 不然会出现乱码
    f = open('data.csv', mode='a', encoding='utf-8')
    csvwriter = csv.writer(f)
    for it in result:
        dic = it.groupdict()
        # strip的作用是去除空白
        dic['year'] = dic['year'].strip()
        csvwriter.writerow(dic.values())
    # 养成良好习惯 每次都要关闭
    f.close()
    print('over')
#  刚开始只能拿到25条数据 所以需要循环改变起始位置的值 每次加25 直到请求完250条的数据
for i in range(0,250,25):
    get_douban_list(i)