python通过集合和队列爬取豆瓣电影数据

爬虫代码说明

定义一个起始的url地址,通过爬虫程序自动获取网页中的所有地址,并将所获取到的url地址放入集合(主要是去重)中,然后将集合中的数据添加到队列中,然后依次爬取。

代码示例

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import requests
from requests.compat import urljoin   #调用的是urllib.parse中的urljoin方法
from pprint import pprint
from collections import deque
from bs4 import BeautifulSoup
import pandas as pd

movie_data = []   #获取到电影数据
q = deque()       #队列,保存需要抓取的目标
url_set = set()  #过滤已经抓取过的地址,防止重复


def fetch(url,count=1):
    '''获取网页内容,设置最大请求次数3,如果超过三次,返回None'''
    headers = {
        "User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Mobile Safari/537.36",
    }
    session = requests.Session()
    session.headers = headers
    if count < 3 :   #最大请求次数设置
        try:
            print('正在获取当前的的地址为:', url)
            return session.get(url).content.decode('utf-8')
        except Exception:    #捕捉到异常后,请求次数加 1,重新调用获取网页内容方法
            print('出现异常,开始重试')
            count += 1
            return fetch(url,count)
    else:
        return None


def parse(html):
    '''解析网页内容,并获取所需要的数据,同时将所有要爬取的url放入到队列(提取用set去重)中'''
    soup = BeautifulSoup(html,'lxml')
    #主要获取的数据是名称、剧情、评分、多少人评价
    for line in soup.select('ol.grid_view li'):
        movie_data.append({
            'name': line.select('div.hd a span')[0].text,
            'plot':','.join(line.select('div.bd p')[0].text.strip().split()[-2:]),
            'score': line.select('div.bd div.star span')[1].text,
            'comment_count':line.select('div.bd div.star span')[3].text.split(r'人评价')[0]
        })

    #将获取的所有地址先用集合去重,并添加到队列中
    for item in soup.select('div.paginator a'):
        if urljoin(start_url,item.get('href')) not in url_set :
            url_set.add(urljoin(start_url,item.get('href')))
            q.appendleft(urljoin(start_url,item.get('href')))


if __name__ == "__main__":
    start_url = 'https://movie.douban.com/top250?start=0&filter='  # 起始页面
    q.appendleft(start_url)
    url_set.add(start_url)
    while len(q):
        url = q.pop()   #取出队列中的url地址
        html = fetch(url)  #获取文本内容
        if html:   #如果获取到的文本内容不为none,则开始提取数据
            parse(html)  #提取所需要的数据

    pprint(movie_data)   #打印数据

    #将数据保存到csv文件中
    df = pd.DataFrame(movie_data)
    df.to_csv('movie.csv',index=False)

你可能感兴趣的:(python,python,爬虫,集合,队列)