前言

第一次接触爬虫,这篇博客用于记录学习的过程,将持续进行更新与修正,希望大家指正错误。本文所学习的案例为:爬取豆瓣电影的评分、评价等信息,进行数据分析。

一、学习爬虫前所需掌握的内容

我们进入豆瓣官网,我现在们想要爬取电影的评分、评价等信息。
在这里插入图片描述
提取这些信息用处很大,例如对于评价信息,可以提取里面的关键词等信息,并进行分析做一个词云图。
在这里插入图片描述


如果我们需要爬取这些信息,则需要以下基础:
①会使用Python完成相关代码
②会分析html
③会使用csv文件、sql存储数据

二、爬取数据

2.1 如何存储数据

由于是入门,我们使用csv文件存储数据,csv又叫逗号分隔符。使用csv文件存储文件的相关代码如下所示:

import csv  # 利用csv模块完成数据读取与存储的相关操作

# 新建一个list,存储一些信息
goods = [[1, 'jack', 18],
         [2, 'Lucy', 19],
         [3, 'Lily', 18],
         [4, 'Tom', 20]
         ]

# 正常使用open步骤如下:即首先创建文件流,然后进行操作,最后关闭文件流。
# f = open('persons.csv')
# ......
# f.close()
# 但是有时候会忘记关闭文件流,导致资源浪费,所以可以使用with。
# 在with的缩进里面执行文件相关操作,当超出with的缩进时,资源自动释放。

# 默认的文件读写模式为 文本模式 t
# 写入所有图片、音乐、视频       mode='wb'
# 写入普通文本                 mode='wt'

# Windows系统写入内容时,具有内容的各行之间会出现空白行,所以需要加上newline=''。具体原因参见博客中的链接

# 写内容到文件中
with open('persons.csv', mode='wt', newline='') as f:
    w_file = csv.writer(f)    # 将f管道升级为csv管道
    w_file.writerows(goods)   # 写入内容
    print('写入完毕')

# 读取文件中的内容
with open('persons.csv', mode='r') as f:
    r_file = csv.reader(f)
    for row in r_file:
        print(row)

Windows系统的用户有一些需要注意的地方,即写入数据到csv文件里时会出现空行,具体原因参见:关于python中csv模块writerows()功能写入二维列表数据时会出现空行的一点思考

2.2 获取html网络数据

获取网络数据需要使用request模块,官方文档链接:request官方文档
在这里插入图片描述


现在我们需要了解浏览器的开发者工具,因为通过开发者工具可以查看请求和响应的详细信息。我们在浏览器页面右键点击,选择检查元素
在这里插入图片描述


接着便会弹出以下界面,其中Element便是html代码。
在这里插入图片描述


我们选择Network,查看响应的相关信息。
在这里插入图片描述


其中Doc文件里面信息重要,界面如下。在General一栏中,Request URL代表我们要访问的地址。Request Method代表请求的方法,有GET和POST两种。
在这里插入图片描述


我们可以分析里面Request Headers的内容,看看我们是发送了一个什么东西让服务器给了我们response并允许我们访问。Request Headers中User Agent最为重要,它表示了当前是谁在访问。服务器通过User Agent认为是浏览器在进行访问。
在这里插入图片描述


我们开始进行访问,需要保存的是响应的返回内容。
在这里插入图片描述


代码如下:

import locale    # 查看系统的编码方式
import requests

# 一个字典,保存User-Agent信息
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 OPR/78.0.4093.231"
}

# 使用requests发送get类型的请求,同时将requests伪装成由浏览器发起
url = 'https://movie.douban.com/explore#!type=movie&tag=热门&sort=recommend&page_limit=20&page_start=0'
response = requests.get(url, headers=headers)      # headers参数需要输入一个子字典类型的参数
code = response.status_code                        # 返回码,正确时为200

# 看一下系统的编码方式,Windows默认是GBK。
# print(locale.getpreferredencoding(False))

if code == 200:
    # 获取的响应数据
    data = response.text
    # 将相应数据保存到douban.html文件中
    # open函数采用的编码方式依赖于系统,而我们在pycharm中打开html文件是使用UTF-8。因此,使用open函数时将编码方式更改为UTF-8
    with open('douban.html', mode='w', encoding="utf-8") as f:
         f.write(data)
else:
    print('请求有误!')

得到返回的html原始数据后,我们看一看,并在浏览器中打开。
在这里插入图片描述
我们发现效果如下,电影的信息都不显示,说明我们想要的信息不在这个链接。
在这里插入图片描述

2.3 获取json网络数据

因此,我们得继续回去分析。只要我们的数据没在Doc里面,那么加载方式可能是异步加载。如何验证是否是异步加载的呢?操作步骤如下:
在这里插入图片描述
我们对比几次的URL如下:
Request URL: https://movie.douban.com/j/search_subjects?type=movie&tag=%E8%B1%86%E7%93%A3%E9%AB%98%E5%88%86&sort=time&page_limit=20&page_start=0

Request URL: https://movie.douban.com/j/search_subjects?type=movie&tag=%E8%B1%86%E7%93%A3%E9%AB%98%E5%88%86&sort=time&page_limit=20&page_start=20

Request URL: https://movie.douban.com/j/search_subjects?type=movie&tag=%E8%B1%86%E7%93%A3%E9%AB%98%E5%88%86&sort=time&page_limit=20&page_start=40


我们可以发现只是最后的page_start不一样。我使用浏览器打开page_start=20对应的URL,界面如下,返回了json信息。
在这里插入图片描述


我们可以得到:
Document返回html格式数据,格式如下:

<html>
......
<html>

XHR(ajax)返回json格式数据,格式如下:

{
data:["",""]
}

如果觉得json格式较乱,可以使用bejson进行格式化校验,让格式更清晰。
在这里插入图片描述
获取json数据代码如下:

import requests

headers = {
    "User-Agent": "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 OPR/78.0.4093.231"
}

url = 'https://movie.douban.com/j/search_subjects?type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=0'
response = requests.get(url, headers=headers)
code = response.status_code

if code == 200:
    data = response.json()    # 获取的响应数据是json类型
    print(type(data))         # data的类型是string
    data = str(data)          # 将字典类型转成str类型
    with open('movies.txt', mode='w', encoding="utf-8") as f:
        f.write(data)
else:
    print('请求有误!')

2.4 获取图片数据

如果我们想提取电影的海报图片,首先查看bejson格式化后的json信息。
在这里插入图片描述
可以看出cover项对应的应该就是电影海报所在位置,我们复制网址并检查,发现正是存储电影海报的位置。
在这里插入图片描述


我们将该网址设置为需要爬取的URL,代码如下:

import requests

headers = {
    "User-Agent": "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 OPR/78.0.4093.231"
}

url = "https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2615830700.webp"
response = requests.get(url, headers=headers)
code = response.status_code

if code == 200:
    # 获取的响应数据是二进制
    data = response.content
    with open('picture.jpg', mode='wb') as f:
        f.write(data)
else:
    print('请求有误!')

爬取图片如下:
在这里插入图片描述

三、提取数据

将各类数据爬取后,我们开始从中提取出数据。我们可以使用XPATH,它能够解析html,也能解析xml。XPATH的详细语法可参照:XPATH语法

3.1 提取百度热搜信息

我们从最开始爬取的百度html文件如下:
在这里插入图片描述
浏览器中打开后界面如下,我们如何从中提取出热搜信息呢?
在这里插入图片描述


我们可以看出,热搜信息位置如下:
在这里插入图片描述
剩余的热搜信息(点击换一批可以看到)则在这里:
在这里插入图片描述


提取热搜信息代码如下:

import requests
from lxml import etree

headers = {
    "User-Agent": "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 OPR/78.0.4093.231"
}
url = 'https://www.baidu.com'

response = requests.get(url, headers=headers)
code = response.status_code

if code == 200:
    data = response.text
    # 将获取的网络数据交给etree进行解析
    html = etree.HTML(data)
    hotsearchs = html.xpath('//ul[@class="s-hotsearch-content"]/li/a/span[2]/text()')
    print(hotsearchs)
else:
    print('请求有误!')

效果如下:
在这里插入图片描述

3.2 提取豆瓣同城近期活动信息

希望提取的豆瓣同城近期活动信息如下图所示:
在这里插入图片描述


我们希望提取活动标题和时间信息。其中,活动标题所处位置如下:
在这里插入图片描述


活动时间所处位置如下:
在这里插入图片描述


提取标题和时间信息代码如下:

import requests
from lxml import etree
import re
import csv

# 1. 发出请求,获取响应数据
headers = {
    "User-Agent": "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 OPR/78.0.4093.231"
}
url = 'https://beijing.douban.com/events/week-all'
response = requests.get(url, headers=headers)

if response.status_code == 200:
    data = response.text
    # 2. 解析数据
    html = etree.HTML(data)
    titles = html.xpath('//ul[@class="events-list events-list-pic100 events-list-psmall"]/li/div[2]/div/a/span/text()')
    print(titles)
    times = html.xpath('//ul[@class="events-list events-list-pic100 events-list-psmall"]/li/div[2]/ul/li[1]/text()')
    print(times)

    # 处理times中的\n和空格
    # 准备一个列表times1存放处理好的数据
    times1 = []
    for t in range(1,len(times),4):
        ti = re.sub(r'\s+','',times[t])
        times1.append(ti)
        print(ti)
    # 3. 存储数据
    titles = zip(titles, times1)
    with open('tongcheng.csv', mode='w', newline='', encoding='utf-8') as f:
        w_file = csv.writer(f)
        w_file.writerows(titles)
else:
    print('error')

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐