从零开始学爬虫(一)

64 阅读3分钟

数据收集和分析是一项非常耗时耗力的工作,作为IT民工,应该让程序代替我们完成这类机械重复类的工作。网络爬虫就是一项来解放我们双手的技术。

本篇文章主要是介绍一下爬虫的简单使用。

什么是爬虫

网络爬虫,又叫做网络蜘蛛(Web Spider)。它可以根据网页地址(URL)爬取网页内容(URL就是我们在浏览器中输入的网站链接)

最简单的爬虫就是用程序代码模拟我们访问url的操作(http Get/Post),然后获取网站的访问信息从而获得网站内容。

一般情况下,我们还需要对网站内容进行过滤,提取,加工等一系列操作,才能获得我们需要的数据。同时,直接这么curl网站的效率也是比较低的(需要考虑如何并发,分布式爬虫等)。

Prerequisite 先决条件

本文章的所有代码运行环境如下,如果不同环境可能需要一定的修改

  • python 3.9.7
  • pycharm IDE
  • Mac M1

网上随便找了一个用于测试爬虫的网站

movie.douban.com/top250

image.png

Step 1 抓取数据

爬虫学习的第一步是根据URL获取网页内容,我们一般使用request库进行信息抓取。

安装第三方库

pip install requests

requests 包主要提供下列这些方法来向网站发起请求

image.png

import requests

if __name__ == '__main__':
    target = 'https://movie.douban.com/top250'

    req = requests.get(target)
    print(req.status_code)  # 打印返回码
    print(req.text)  # 打印返回内容

使用requests包可以访问url并且获得返回内容

但如果网站有反爬机制的话,会返回错误码418,可以通过增加header解决

import requests

if __name__ == '__main__':
    headers = {
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36'}
    target = 'https://movie.douban.com/top250/'

    req = requests.get(target, headers=headers)

    print(req.status_code)  # 打印返回码
    print(req.text)  # 打印返回内容

header 可以通过F12 查看

image.png

Step 2 解析html 信息

提取html内容的方式有很多,正则表达式和一些第三方库,这里使用BeautifulSoup库来进行解析。 官方参考文档

pip install bs4   
pip install beautifulsoup4

在要解析的网站上,我们用F12查看页面元素,假如我们要爬取的是每部电影的电影名,

image.png

image.png 所以需要找到所有class=title的span标签就能提取出电影名

html.parser是python标准库提供解析器

import requests
from bs4 import BeautifulSoup

if __name__ == '__main__':
    headers = {
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36'}
    target = 'https://movie.douban.com/top250/'

    req = requests.get(target, headers=headers)

    soup = BeautifulSoup(req.text, 'html.parser')
    nameList = soup.find_all('span', class_="title")
    res = []
    for i in range(0, len(nameList) - 1, 1):
        if nameList[i].string.find('/') != -1:
            res[len(res) - 1] = res[len(res) - 1] + nameList[i].string
            continue
        res.append(nameList[i].string)
    print(res)

image.png

image.png

Step 3 整理并获取全部数据

经过前面两个步骤,已经可以获得一页的电影名数据,下面整理一下前面的代码,然后获取全部的top250电影名

import requests
from bs4 import BeautifulSoup
import time
from tqdm import trange


class downloader:
    def __init__(self):
        self.headers = {
            'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) '
                          'Chrome/106.0.0.0 Safari/537.36 '
        }
        self.filmNames = []
        self.target = 'https://movie.douban.com/top250?start={}'

    def get_download_by_page(self, start):
        tar = self.target.format(start)
        req = requests.get(tar, headers=self.headers)

        soup = BeautifulSoup(req.text, 'html.parser')
        nameList = soup.find_all('span', class_="title")

        res = []
        for i in range(0, len(nameList) - 1, 1):
            if nameList[i].string.find('/') != -1:
                res[len(res) - 1] = res[len(res) - 1] + nameList[i].string
                continue
            res.append(nameList[i].string)
        self.filmNames.extend(res)

    def write_to_file(self, filename):
        with open(filename, 'a', encoding='utf-8') as f:
            for name in self.filmNames:
                f.write(name + '\n')


if __name__ == '__main__':
    dl = downloader()
    for i in trange(0, 250, 25):
        dl.get_download_by_page(i)
        time.sleep(1)

    dl.write_to_file('FilmName.txt')

tqdm是用来展示进度条的库

获取到所有的电影名后保存到本地文件中

image.png

image.png