爬虫(二)之加入缓存

缓存就是将页面信息下载下来,避免二次下载

import os
import requests
from pyquery import PyQuery as pq

"""
这个爬虫可以爬 10 个页面, 把所有 TOP250 电影都爬出来
并且加入了缓存页面功能
再也不用重复请求了(网络请求很浪费时间)
这样做有两个好处
    1, 增加新内容(比如增加评论人数)的时候不用重复请求网络
    2, 出错的时候有原始数据对照(比如 消失的爱人 没有 quote)
"""

class Model():
    def __repr__(self):
        name = self.__class__.__name__
        properties = ('{}=({})'.format(k, v) for k, v in self.__dict__.items())
        s = '\n<{} \n  {}>'.format(name, '\n  '.join(properties))
        return s


class Movie(Model):
    def __init__(self):
        self.name = ''
        self.other = ''
        self.score = 0
        self.quote = ''
        self.cover_url = ''
        self.ranking = 0
def cached_page(url):
    folder = 'cacheddouban'
    if not os.path.exists(folder):
        os.makedirs(folder)

    # https://movie.douban.com/top250?start=100
    filename = '{}.html'.format(url.split('=', 1)[-1])
    path = os.path.join(folder, filename)
    print(path)

    if os.path.exists(path):
        with open(path, 'rb') as f:
            s = f.read()
            return s
    else:
        # 发送网络请求, 把结果写入到文件夹中
        r = requests.get(url)
        with open(path, 'wb') as f:
            f.write(r.content)
            return r.content
  • 如果不存在目标文件夹,则新建文件夹
  • os.path 返回当前文件的容器路径
  • 建立文件存储页面信息,文件名根据当前 url 来
  • os.path.join() 定位到当前文件路径
  • 如果存在当前路径,读取返回就行
  • 如果不存在,就将获取的页面内容存进去

注意:
s == r.content

def movie_from_div(div):
    e = pq(div)
    m = Movie()
    m.name = e('.title').text()
    m.other = e('.other').text()
    m.score = e('.rating_num').text()
    m.quote = e('.inq').text()
    m.cover_url = e('img').attr('src')
    m.ranking = e('.pic').find('em').text()
    return m

def movies_from_url(url):
    page = cached_page(url)
    e = pq(page)
    items = e('.item')
    # 调用 movie_from_div 
    movies = [movie_from_div(i) for i in items]
    return movies

def main():
    for i in range(0, 250, 25):
        url = 'https://movie.douban.com/top250?start={}'.format(i)
        movies = movies_from_url(url)
        print('top250 movies', movies)

if __name__ == '__main__':
    main()

你可能感兴趣的:(爬虫(二)之加入缓存)