爬虫入门教程

3,699次阅读
没有评论

文章目录


前言

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

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

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

如果我们需要爬取这些信息,则需要以下基础:
①会使用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')

神龙|纯净稳定代理IP免费测试>>>>>>>>天启|企业级代理IP免费测试>>>>>>>>IPIPGO|全球住宅代理IP免费测试

相关文章:

版权声明:Python教程2022-10-24发表,共计6177字。
新手QQ群:570568346,欢迎进群讨论 Python51学习