Python爬虫实践——静态网页抓取

Python静态网页抓取

最近学习了利用Python爬虫进行静态网页的抓取,并进行一点简单的分析保存。下面是整个学习的过程:

实践要求目的

访问豆瓣电影Top250的网页https://movie.douban.com/top250,并爬取所有电影的电影名、导演、主演、上映年份、电影分类和评分。并将结果保存到Excel中。

爬取过程

爬取网页

利用Python中的requests库,可以直接爬取网页的源代码。

  1. 我们首先先利用DOS安装requests
pip install --user requests

根据百度上的pip安装教程,利用pip安装时,直接输入pip install +(库名),但无法安装成功,根据自带的提示,加上一个–user即可成功安装。

  1. 在Python中导入requests后,利用库函数get,直接获取网页源代码。
link = 'https://movie.douban.com/top250'
r = requests.get(link,headers,timeout=20)

get函数中:

  • 第一个参数就是爬取网页的url
  • 第二个header是请求头
  • 第三个设置响应超时的时间;

下面我们来详细说明一下后两个参数。

请求头Headers提供我们关于请求、响应或者是其他的一些发送实体的信息,如果没有请求头或请求头和网页对应不正确,那么我们爬取的结果就有可能错误。

如何找一个网页的请求头呢?
我们进入到豆瓣电影top250的网页按f12进入开发者模式;
Python爬虫实践——静态网页抓取_第1张图片
点击Network,并刷新界面。Python爬虫实践——静态网页抓取_第2张图片
点击网页的名字,再点Headers,在其中我们就可以找到请求头的内容,并按照下面的格式在Python中保存。

 headers ={'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36',
              'Host':'movie.douban.com'}

说完请求头,下面我们来说设置响应时间。
因为有时候爬虫会遇到服务器长时间不响应不返回的情况,这时爬虫就会等待,我们设置一个无响应返回的时间,到达时间截点还未响应则返回。

  1. 接下来我们就会发现,上面这个网页link只有25个电影,总共250个电影分布在10页;我们单击第二页,发现网址变了:https://movie.douban.com/top250?start=25;第三页:https://movie.douban.com/top250?start=50;我们就可以发现规律,每多一页,链接的最后的数字就加25。

我们就可以设置一个for循环来不断更新爬取的网页。

 for i in range (0,10):
        link = 'https://movie.douban.com/top250?start=' + str(i*25)
        r = requests.get(link,headers=headers,timeout=20)

到这里我们就可以检验一下上述过程是否正确,我们是否爬取成功。

我们将每页的响应状态码打印出来。

 print('Page',i,' ',r.status_code)

Python爬虫实践——静态网页抓取_第3张图片
当状态码为200时,爬取成功。

分析网页

经过上述过程我们就可以得到网页的HTML代码了,但我们不需要这么多东西,我们需要从中分析提取出我们想要的东西。

  1. 我们需要用到第三方库bs4中的BeautifulSoup
    通过pip进行安装并导入,方法与上面的相同。
pip install --user bs4
from bs4 import BeautifulSoup	#导入

BeautifulSoup能够自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。BeautifulSoup能将html解析为对象进行处理,全部页面转变为字典或者数组,相对于正则表达式的方式,可以大大简化处理过程。

我们建立一个BeautifulSoup对象soup来解析网页。

soup = BeautifulSoup(r.text,"lxml")

这里的lxml是Python中解析HTML页面的一个库,是BeautifulSoup解析的一个固定搭配之一。(若代码在这里报错,可能是因为没有安装lxml库,pip安装即可。)

  1. 我们先通过浏览器的开发者模式观察一下发现Python爬虫实践——静态网页抓取_第4张图片
    电影名保存在了div标签下的class = “hd”中,而其他我们所需要的信息则保存到了div标签下的class = “bd”中。

我们先讨论电影名的提取。其余的项目都基本类似。

我们直接采用soup中的find_all函数,其中soup中有两个函数,一个是find一个视find_all,find函数返回的是第一个符合搜索条件的结果,find_all则返回所有结果,这里根据需要我们使用find_all,并将结果保存到一个list中。

div_list1 = soup.find_all('div',class_='hd')

Python爬虫实践——静态网页抓取_第5张图片
这里将list打印并截取第一个《肖申克的救赎》的结果,即div_list[0],同时我们对比豆瓣网页的源代码的形式。我们就可以提取出名字来了。

电影名是保存在标签a下面的第一个span标签里的。利用循环就可以把第一页的所有电影的名字保存下来。

 for each in div_list1:
    #中文名
    movie_name = each.a.span.text.strip()
    movies_name.append(movie_name)

这里movies_name为保存所有电影名的list。

这样我们就保存了整个top250的电影的名字了。我们输出出来检查一下。
Python爬虫实践——静态网页抓取_第6张图片

  1. 接下来的其他项目的过程基本相同。
    我们将find_all函数中的第二个参数换成:class=“bd”,并保存在一个list中。

这里问题来了。我们需要的内容没有保存到一个a和span里面,而是一个标签p里面,如果我们将a直接换成p,跳过span部分,报错!,这怎么办呢?
我们需要换成另一个函数在后面:contents,contents可以输出p下面的所有内容,并返回一个list。我们现在就可以在这个list中找我们需要的内容了。

我么还是先输出

div_list2=soup.find_all('div',class_='bd')

的结果。(为便于观察,我们直接采用断点+单步调试的方法,查看结果)
Python爬虫实践——静态网页抓取_第7张图片
从div_list2的第二项开始才是我们需要的内容,所以循环时应从div_list2[1]开始
在这里插入图片描述
each.p.contents中只有第1项和第3项是我们需要的,所以我们list的下边确定为contents[0]和contents[2]。

先说contents[0]。我们通过strip函数split函数对字符串进行处理,去掉一些杂项。

movie = each.p.contents[0].strip().split('\xa0')

在这里插入图片描述
当当当当,结果就出来了。

当我们输出所有结果时,发现不对了。报错! 还是数组越界的错,这次又是为什么呢?明明第一个成功提取出来了,第二个也成功了。

我们来看豆瓣的网页在这里插入图片描述
最后这里居然没有显示全。也就是说,当后面遇到某部电影导演特别多,或名字特别长时,主演就变成了"…"显示不出来了最为关键的是,上面的movie返回的list长度就从4变为2了,当我们试图采用上面的

actor = movie[3]

时,自然就会报错。

这怎么解决呢?

这个问题我实质上没有从根本上解决,因为这是豆瓣的网页的问题,这个html没有的字我也没办法加上去,除非是点进去每一个电影链接中查看,但这250个电影的具体链接之间没有直接的关联,也许有办法可以提取到新的网址,从而重新爬取新网址,然后再分析,再获取。从这个方向想,好像又太麻烦了。
包括上面有人可能会怀疑,我都提取了中文电影名了,为什么不接着提取英文名和港台名。这里挖一个小坑,有兴趣的可以试着提取一下英文名和港台名。
当然也有可能是我水平不够不知道什么厉害的方法。

在这里我们直接采用if判断语句,根据movie的长度进行判别。

if len(movie)==4:
    movie_dir  = movie[0][4:]
    movie_actor = movie[3][4:]
else:
    movie_dir  = movie[0][4:]
    movie_actor = '...'

剩下的部分就没有什么坑了,跟着上面的步骤,就可以提取出电影的上映年份,国家,分类,评分了。在这里不再重复说明。

保存数据

提取分析完所有的数据,并保存在movies_name, movies_dir, movies_actor, movies_time, movies_nation, movies_class, movies_grade这些list中。接下来一步就是如何保存到Excel中,方便我们进行进一步的工作了。

  1. 保存到excel我们用到一个Python和Excel关联的库xlwt

xlrd和xlwt两个库是Python文件操作中,关联Excel的两个,分别对应Excel的读和写。这里写入,使用xlwt。直接通过pip安装即可。

  1. 直接利用xlwt的函数:
workbook = xlwt.Workbook(encoding = 'utf-8')
worksheet = workbook.add_sheet('豆瓣top250')

xlwt.Workbook(encoding = ‘utf-8’) —— 以utf-8的编码方式建立Excel工作表。
add_sheet(‘豆瓣top250’) —— 在表中建立名为“豆瓣top250”的工作簿。

建立好了,接下来就是写入数据。就用一个函数就可以了。
worksheet.write(r,c,str)
其中,r表示行,c表示列,str表示内容。
把我们list的内依次存入即可。

最后,保存Excel:
save(filename)
filename是文件保存的路径。

统计结果(部分)

Python爬虫实践——静态网页抓取_第8张图片

完整代码下载

https://download.csdn.net/download/weixin_42182525/11649909

你可能感兴趣的:(Python)