爬取动态页面的实例——爬取豆瓣电影排行榜前250名

目的:爬取豆瓣电影排行榜前250名的信息

目标网址:豆瓣电影Top 250


在此之前你需要知道

  • 静态页面的基本爬取方法
  • 利用selenium库来模拟浏览器行为

静态页面的爬取方法

具体就是利用request库和BeautifulSoup函数,可参考我之前的两篇博客

  • 有关网络爬虫的一个简单教程(一)

  • 有关网络爬虫的一个简单教程(二)


动态页面的爬取方法

接下来我们将介绍什么是动态页面(不敢兴趣的童鞋可以直接跳过)

所谓的动态网页,是指跟静态网页相对的一种网页编程技术。静态网页,随着html代码的生成,页面的内容和显示效果就基本上不会发生变化了——除非你修改页面代码。而动态网页则不然,页面代码虽然没有变,但是显示的内容却是可以随着时间、环境或者数据库操作的结果而发生改变的

简单的说动态网页的内容会发生变化,而静态网页的内容基本不会发生变化,这是两者最本质的区别。


动态页面的几种类型

一般的我们在爬取动态页面的时候会遇到以下几种情况

  1. ajax异步加载,最直观的表现会有以下几点之一
  • 利用开发者工具看到的代码与鼠标右键看到的源代码是不一样的(应用开发者工具看到的代码是经过浏览器渲染之后的代码)
  • 相关内容在利用开发者工具看到的代码中无法找到(数据可能放在某个数据包中,这是异步加载的最核心的东西,可以实现局部更新页面)

    2.内容在多个页面中(如常见的下一页等),也会有以下几种类型

  • 下拉滚动条内容会不断刷新(以今日头条为例)
  • 点击后网址发生变化(以豆瓣网为例)
  • 点击后网址不发生变化(比如qq空间中点击说说后,网址不变但是相关内容变化了)

关于异步加载的网站的爬取主要有以下两种方法

  • 直接从JavaScript中采集数据,也就是通常所说的抓包
  • 利用selenium库模拟浏览器行为(太慢,一般不会使用)

关于内容在多个页面中的网站爬取一般采用

  • 利用selenium库模拟浏览器行为

以上都是我个人的理解,如有不正确的地方还请大家多多指正,本文主要解决的是第2种动态页面的第二种情况吗,即点击相关选项后网址会发生变化的网站。


在此之前需要你安装谷歌浏览器的驱动Chromedriver,可根据你当前的谷歌浏览器版本(右上角三个点——帮助——关于,即可查看当前浏览器的版本)下载对应的驱动,(当然,你也可以下载其他浏览器的版本)。

接下来你需要了解selenium webdrive使用,我们主要会用到以下方法

from selenium import webdriver
driver=webdriver.Chrome()#调用谷歌浏览器
driver.get(url)#打开网址
driver.quit()#关闭浏览器
driver.find_element_by_class_name()#根据类名查找元素
driver.click()#点击
driver.page_source #获取当前源码
driver.current_url#获取当前网址

我们可以利用前面已经学会的静态页面的爬取方法来爬取豆瓣网电影排行榜前250名的信息,我们发现每点击一次,页面的网址会发生变化,但是每个页面都是静态页面,所以思路如下

输入目标网址——爬取当前页面——点击下一页——获取当前网页的网址——更新网址——爬取当前页面

很显然这是一个循环,可以利用while语句来实现,判断循环终止的条件就是

无法点击下一页(说明当前页已经是最后一页了)


最终代码

from bs4 import BeautifulSoup
from selenium import webdriver
import csv


def get_content(url, content):
    chrome_options = webdriver.ChromeOptions()
    chrome_options.add_argument('--headless')
    chrome_options.add_argument('--disable-gpu')
    driver = webdriver.Chrome(options=chrome_options,
                              executable_path="D:/wangyang/其他软件/chromedriver.exe")  # 打开谷歌浏览器,这里使用的无头浏览器,也可以把第一个参数删去,同时删除前三行代码

    driver.maximize_window()  # 最大化窗口

    driver.get(url)  # 打开网页

    # 构造BeautifulSoup类
    bs = BeautifulSoup(driver.page_source, "html.parser")
    body = bs.body
    # print(body)
    if content == []:
        content_title = []  # 存储第一行标题
        data = body.find("div", {"id": "content"}).find("h1")
        content_title.append(str(data.get_text()))
        content.append(content_title)
        content_subtitle = ["电影名", "导演/主演/时间/国家/类型", "评语"]  # 每一列的标题
        content.append(content_subtitle)
    # 爬取电影
    data = body.find("ol", {"class": "grid_view"})
    Li = data.find_all("li")
    for li in Li:
        every_content = []  # 存储每一个电影的信息
        title = li.find("div", {"class": "hd"}).find(
            "span", {"class": "title"}).get_text()#爬取电影的名字
        every_content.append(str(title))
        director = li.find("div", {"class": "bd"}).find("p").get_text()#爬取电影的导演等信息
        every_content.append(str(director))
        comment = li.find("div", {"class": "bd"}).find(
            "p", {"class": "quote"}).find("span").get_text()#爬取电影的相关评论
        every_content.append(str(comment))
        content.append(every_content)
    driver.find_element_by_class_name("next").click()#点击下一页
    url = driver.current_url#获取当前页面的url
    driver.quit()#关闭网页
    return url, content, body


url = "https://movie.douban.com/top250"
content = []
url, content, body = get_content(url, content)
while True:
    # 判断是否到达最后一页
    if body.find("span", {"class": "next"}).find("a") == None:
        break
    else:
        url, content, body = get_content(url, content)
#写入文件
file_name = "D:\\wangyang\\练习的python程序\\网络爬虫\\爬取豆瓣网前250名的电影信息.csv"
with open(file_name, "a", errors="ignore", newline="") as f:
    f_csv = csv.writer(f)
    f_csv.writerows(content)

目前就实现了爬取豆瓣网前250名的电影信息,但是还有不足之处,这里只爬取了电影的文本信息,后面还有继续改进的空间,比如爬取电影的图片,观影人的评论等等,我在GitHub上传的该项目,感兴趣的可以一起来试试。

https://github.com/smiletreasure/crawler_douban.git

 

你可能感兴趣的:(网络爬虫)