用Python从网页爬取数据,网上相关文章很多,但能让零基础初学者轻松上手的却很少。可能是有的作者觉得有些知识点太简单不值得花费精力讲,结果是难者不会会者不难,初学者常常因此而蒙圈。本人也是小白,刚摸索着爬了两个简单的网页数据,经历了初学者易犯的各种糊涂,特总结分享一下,希望能对小白们有用。
python爬网络数据,方法很多。不同的python版本、不同的模块、库,对应代码都不同。所以,在看他人代码时,需要搞清代码环境所用的版本和使用的模块库等信息。因为如果环境不同,相同的代码也可能没用。初学者往往看到一篇文章讲的代码,复制过来就用,结果就是各种错误,这就是因为环境不同造成的。
没有模块的,pip安装一下就好。安装方法:点击电脑左下角开始——输入cmd回车,弹出cmd.exe界面——在界面上输入pip install requests回车,稍后,提示安装成功即完成了requests模块的安装。BeautifulSoup解析库是属于bs4模块的一个功能块,所以,用pip安装时,要安装pip install bs4。
建好了代码环境,就可以开始爬数据了,无论什么代码环境,爬虫核心都是这4步。对新手来说,每一步都不简单,我们通过一个简单的爬取一篇小说代码,来看看到底是怎么爬数据的。
3-1 拟爬取的网络小说截图
如图3-1,我们试着把这篇小说爬下来保存为txt文件,按照爬虫4部曲,我们逐步来看:
1)、发出请求
用代码向网络发出请求,请求访问某个网址,首先我们得在代码中给出具体的网址信息,比如上面截图的网址是:https://www.biqiuge.com/book/4772/2940354.html
那这个网址是怎么得到的呢,常规方法是通过浏览器的开发者工具,我是用的360浏览器,点击右上角的工具菜单,点击开发者工具即可,打开后的界面如下图3-2:
图3-2 开发者工具窗口
顶部菜单选择Network,中间圆圈选择Preview,通过选择左侧红色方框内的不同选项,观察Preview下部的内容,当能看到我们想要的文字时人(如图3-3),就说明找到了。
图3-3 箭头指示的就是准备爬取的数据
这时点击Preview左侧的Header面板,得到下图3-4中的url就是我们要找的网址。复制后,粘贴到代码里就能发出请求了。
图3-4 找到请求的网址
有细心的会看到,这个网址和我们平常浏览网页时地址栏里的网址一样啊,还用这么麻烦?
3-5 浏览器地址栏网址
这两个网址确实是一样的,是不用这么麻烦,直接从地址栏复制就可以。但很多时候,我们要爬取的网页数据并不在浏览器地址栏的那个网址里,这个时候就需要通过上面的那个开发者工具方法去找。
有了网址,发出请求的代码为:
url = "https://www.biqiuge.com/book/4772/2940354.html" # 要爬取数据的网址
response = requests.get(url) #发出访问请求,获得对应网页
访问请求的反馈结果放在response里了,这时我们用print(response)看看这个结果到底是什么?运行结果为:<Response [200]>
这是个什么鬼?怎么不是我们想要的网页内容呢?解释一下:
运行结果的意思是:响应状态为成功。可以放心写后面的代码了。如果出现数字404,就是没找到页面的意思,响应不成功。响应结果还需要解析才能得到网页内容。
2)、获得网页
上面说了,已经请求访问并响应成功了,接下来就是如何获得具体网页内容了。
soup = BeautifulSoup(response.content, 'lxml') # 将获得的网页内容解析写入soup备用
我们用print(soup)看一下结果,就会得到下图3-6的结果:
3-6 代码得到的网页内容
内容与前面在Preview里看到的一样,说明已经成功获得了网页内容。
3)、解析网页内容,获得数据
所有要爬取的数据,都在上面的soup结果里,但还有更多是我们不需要的数据。所以接下来第3步就是对上面的结果内容进行操作,以获得我们想要的内容。
1)根据目标,我们首先要获得小说的标题和章节标题
在开发者工具里,分析网页内容,发现我们的目标之一小说和章节的标题分别位于下图所示位置:
图3-7 找到标题所处位置
A、小说标题“圣墟”在下面两个位置都出现过,写解析代码就可以了:
<a href="/book/4772/">圣墟</a>
<a href='https://www.biqiuge.com/book/4772/' target='_blank' title="圣墟">圣墟</a>
很明显第一个相对比简单点,所以,我们通过解析第一个位置内容来提取出标题“圣墟”
t1 = soup.find('a', href="/book/4772/"').get_text()
代码解析: 上面两处标题都位于<a,....../a>之间,所以“a”就是我们要用的第一个参数,由于有a参数的代码还有很多,为了精准定位就是这个位置的a,我们发现属性href的值不同而且貌似是独一无二的,所以将其作为关键字放进代码里,就得到了此处的这段代码。然后用.get_text()将这段代码里的文字给爬取出来,就得到了我们最终想要的小说标题——“圣墟”。上面的代码如果将href的参数值改为:'https://www.biqiuge.com/book/4772/',也能得到相同的结果
B、章节标题在网页代码中也出现过多次,但是我们只需找到一处解析得到即可,根据上面的经验,我们选最简单的一处为:
<h1>第一章 沙漠中的彼岸花</h1>
编写代码:
t2 = soup.find('h1').get_text()
2)获得小说内容
继续分析网页代码,发现小说内容的位置为:
<div id="content" class="showtxt"><script>App2();</script><br /> 大漠孤烟直......
说明小说内容位于<div ....../div >之间,所以将div作为第一个参数,由于div出现了很多次,所以我们需要继续用此处独有的参数作为关键字,我们将id="content" class="showtxt"同时作为参数放到代码里,这样代码就为:
tt = soup.find('div', id="content", class="showtxt").get_text()
此时,由于class在python里代表“类”,为敏感词,作为关键字放在代码里容易混淆,所以我们将敏感词作为关键字时,需要在其后面加一个下划线,将代码class="showtxt"改为:class_="showtxt"。运行后,小说内容就已经在tt里了。我们可以通过print(tt)看到效果。
4)、保存内容
虽然小说标题、内容都已经爬取到了,但到哪里看呢,我们不可能每次都用python用print()运行后看。我们可以将刚才爬取到的标题、内容,写入到一个txt文件里。这就用到os模块了。
此时运行程序,就能在e盘发现已新生成了文件“小说.txt文件",打开,发现,所有想要的内容已经写入到文件里了如图3-8。但是小说内容没有换行,阅读起来不方便,且前面有个多余的app2()。
图3-8 爬取的效果
为了达到更好的效果,我们将代码:
tt = soup.find('div', id="content", class="showtxt").get_text()
优化为:
tt = soup.find('div', id="content", class_="showtxt").text.replace(' ','n').replace('app2();','n')
即将app2()和空格符都替换为换行符。运行后得到效果为:
图3-9 优化后最终的爬取结果
至此,一个简单的爬取就完成了。
其实,该网址内容完全可以直接复制就能得到,本文之所以还大费周章进行爬取,不过是借用这个简单的静态网页,体验一下爬虫4步骤的流程,为后续批量爬取网页中的小说、图片以及爬取动态网页数据做基础。
# -*- coding:utf-8 -*-
import requests
from bs4 import BeautifulSoup
# 第一步:发出访问请求
url = "https://www.biqiuge.com/book/4772/2940354.html"
response = requests.get(url)
# 第二步:获得网页信息
soup = BeautifulSoup(response.content, 'lxml')
# 第三步:解析网页数据
t1 = soup.find('a', href="/book/4772/").get_text()
t2 = soup.find('h1').get_text()
tt = soup.find('div', id="content", class_="showtxt").text.replace(' ','n').replace('app2();','n')
# 第四步:保存内容
f = open(r"e:小说1.txt", 'a+', encoding='utf-8')
f.write(t1 + 'n')
f.write(t2 + 'n')
f.write(tt)
f.close()
print('下载完成')