实验四作业 20193309 蔡毅敏

2019-2020《Python程序设计》实验四报告

课程:《Python程序设计》
班级:1933
姓名:蔡毅敏
学号:20193309
实验教师:王志强
实验日期:2020年4月12日
必修/选修: 公选课

1. 实验内容

  1. 使用 requests 库抓取网站数据;
  2. 使用 Beautiful Soup 解析网页;
  3. 清洗和组织数据;
  4. 简单地爬虫攻防战;

 

2. 实验过程及结果

实验原理:几乎每一个网站都有一个名为 robots.txt 的文档,当然也有部分网站没有设定 robots.txt。对于没有设定 robots.txt 的网站可以通过网络爬虫获取没有口令加密的数据,也就是该网站所有页面数据都可以爬取。如果网站有 robots.txt 文档,就要判断是否有禁止访客获取的数据。

使用 requests 库请求网站

安装 requests 库

首先在 PyCharm 中安装 requests 库

为此打开 PyCharm,单击“File”(文件)菜单,选择“Setting for New Projects...”命令

选择“Project Interpreter”(项目编译器)命令,确认当前选择的编译器,然后单击右上角的加号

在搜索框输入:requests(注意,一定要输入完整,不然容易出错),然后单击左下角的“Install Package”(安装库)按钮。
安装完成后,会在 Install Package 上显示“Package‘requests’ installed successfully”(库的请求已成功安装)

 

在爬虫过程中需要经历一个叫做网页请求的环节:

网页请求的过程分为两个环节:

  1. Request (请求):每一个展示在用户面前的网页都必须经过这一步,也就是向服务器发送访问请求。
  2. Response(响应):服务器在接收到用户的请求后,会验证请求的有效性,然后向用户(客户端)发送响应的内容,客户端接收服务器响应的内容,将内容展示出来,就是我们所熟悉的网页请求

 

网页请求的方式也分为两种:

  1. GET:最常见的方式,一般用于获取或者查询资源信息,也是大多数网站使用的方式,响应速度快。
  2. POST:相比 GET 方式,多了以表单形式上传参数的功能,因此除查询信息外,还可以修改信息。


所以,在写爬虫前要先确定向谁发送请求,用什么方式发送。

使用 GET 方式抓取数据

复制任意一条首页首条新闻的标题,在源码页面按【Ctrl+F】组合键调出搜索框,将标题粘贴在搜索框中,然后按【Enter】键。
标题可以在源码中搜索到,请求对象是www.cntour.cn,请求方式是GET(所有在源码中的数据请求方式都是GET)

 

 

 

 

 

 

 

 

 

爬得的结果如下:

 

 

 

 

 

分析:

加载库使用的语句是 import+库的名字。在上述过程中,加载 requests 库的语句是:import requests。

GET 方式获取数据需要调用 requests 库中的 get 方法,使用方法是在 requests 后输入英文点号,如下所示:

requests.get

将获取到的数据存到 strhtml 变量中,代码如下:

strhtml = request.get(url)

这个时候 strhtml 是一个 URL 对象,它代表整个网页,但此时只需要网页中的源码,下面的语句表示网页源码:

strhtml.text

使用 POST 方式抓取数据

首先输入有道翻译的网址:http://fanyi.youdao.com/,进入有道翻译页面。

 

 

 

按快捷键 F12,进入开发者模式,单击 Network,

此时内容为空在有道翻译中输入人生苦短”,单击“翻译”按钮

 

 

 

在开发者模式中,依次单击“Network”按钮和“XHR”按钮,找到翻译数据

 

 

 

单击 Headers,发现请求数据的方式为 POST。

 

找到数据所在之处并且明确请求方式之后,接下来开始撰写爬虫。

首先,将 Headers 中的 URL 复制出来,并赋值给 url,代码如下:

url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'

POST 的请求获取数据的方式不同于 GET,POST 请求数据必须构建请求头才可以。

 

将其复制并构建一个新字典:

使用 requests.post 方法请求表单数据

将字符串格式的数据转换成 JSON 格式数据,并根据数据结构,提取数据,并将翻译结果打印出来

import json

content = json.loads(response.text)

print(content['translateResult'][0][0]['tgt'])

 

使用 Beautiful Soup 解析网页

通过 requests 库已经可以抓到网页源码,接下来要从源码中找到并提取数据。Beautiful Soup 是 python 的一个库,其最主要的功能是从网页中抓取数据。Beautiful Soup 目前已经被移植到 bs4 库中,也就是说在导入

Beautiful Soup 时需要先安装 bs4 库。

 

 

 

 

 

安装好 bs4 库以后,还需安装 lxml 库。如果我们不安装 lxml 库,就会使用 Python 默认的解析器。尽管 Beautiful Soup 既支持 Python 标准库中的 HTML 解析器又支持一些第三方解析器,但是 lxml 库具有功能更加强大、速度更快的特点,推荐安装 lxml 库。

 

 

 

Beautiful Soup 库能够轻松解析网页信息,它被集成在 bs4 库中,需要时可以从 bs4 库中调用。其表达语句如下:

from bs4 import   BeautifulSoup

首先,HTML 文档将被转换成 Unicode 编码格式,然后 Beautiful Soup 选择最合适的解析器来解析这段文档,此处指定 lxml 解析器进行解析。解析后便将复杂的 HTML 文档转换成树形结构,并且每个节点都是 Python 对象。这里将解析后的文档存储到新建的变量 soup 中,代码如下:

soup=BeautifulSoup(strhtml.text,'lxml')

接下来用 select(选择器)定位数据,定位数据时需要使用浏览器的开发者模式,将鼠标光标停留在对应的数据位置并右击,然后在快捷菜单中选择“检查”命令,

 

 

 

随后在浏览器右侧会弹出开发者界面,右侧高亮的代码对应着左侧高亮的数据文本。右击右侧高亮数据,在弹出的快捷菜单中选择“Copy”➔“Copy Selector”命令,便可以自动复制路径。

 

 

将路径粘贴在文档中,代码如下:

#main > div > div.mtop.firstMod.clearfix > div.centerBox > ul.newsList > li:nth-child(1) > a

由于这条路径是选中的第一条的路径,而我们需要获取所有的头条新闻,因此将 li:nth-child(1)中冒号(包含冒号)后面的部分删掉,代码如下:

#main > div > div.mtop.firstMod.clearfix > div.centerBox > ul.newsList > li > a

使用 soup.select 引用这个路径,代码如下:

data = soup.select('#main > div > div.mtop.firstMod.clearfix > div.centerBox > ul.newsList > li > a')

 

清洗和组织数据

至此,获得了一段目标的 HTML 代码,但还没有把数据提取出来,接下来在 PyCharm 中输入以下代码:

  1. for item in data:
  2. result={
  3. 'title':item.get_text(),
  4. 'link':item.get('href')
  5. }
  6. print(result)

 

 

 

 

 

爬虫攻防战

如老师在课上说的;

爬虫是模拟人的浏览访问行为,进行数据的批量抓取。当抓取的数据量逐渐增大时,会给被访问的服务器造成很大的压力,甚至有可能崩溃。换句话就是说,服务器是不喜欢有人抓取自己的数据的。那么,网站方面就会针对这些爬虫者,采取一些反爬策略。

服务器第一种识别爬虫的方式就是通过检查连接的 useragent 来识别到底是浏览器访问,还是代码访问的。如果是代码访问的话,访问量增大时,服务器会直接封掉来访 IP。

 

因此,我们只需要构造这个请求头的参数。创建请求头部信息即可,代码如下:

headers={'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'}
response = request.get(url,headers=headers)

正常人1秒看一个图,而个爬虫1秒可以抓取好多张图,比如 1 秒抓取上百张图,那么服务器的压力必然会增大。也就是说,如果在一个 IP 下批量访问下载图片,这个行为不符合正常人类的行为,肯定要被封 IP。

其原理也很简单,就是统计每个IP的访问频率,该频率超过阈值,就会返回一个验证码,如果真的是用户访问的话,用户就会填写,然后继续访问,如果是代码访问的话,就会被封 IP。

这个问题的解决方案有两个,第一个就是常用的增设延时,每 3 秒钟抓取一次,代码如下:

import time
time.sleep(3)

但是,我们写爬虫的目的是为了高效批量抓取数据,这里设置 3 秒钟抓取一次,效率未免太低。其实,还有一个更重要的解决办法,那就是从本质上解决问题。

不管如何访问,服务器的目的就是查出哪些为代码访问,然后封锁 IP。解决办法:为避免被封 IP,在数据采集时经常会使用代理。当然,requests 也有相应的 proxies 属性。

首先,构建自己的代理 IP 池,将其以字典的形式赋值给 proxies,然后传输给 requests,代码如下:

  1. proxies={
  2. "http":"http://10.10.1.10:3128",
  3. "https":"http://10.10.1.10:1080",
  4. }
  5. response = requests.get(url, proxies=proxies)

 

3. 成果分析

具体的过程和实现以及可视化都在过程中一并上传

包括避免IP被封的一些做法不宜实践太多。

4. 实验过程中遇到的问题和解决过程

 

主要是一些import的问题,有些安装不成功会让进程受到极大的干扰

另外有些网站由于私密性较高,无法顺利爬到数据。

需要选择一些类似于中国旅游网这些开放性比较高的网站。

 

5. 结课总结:

有同学问我为什么选择Python。我很喜欢这门语言,因为它的简洁灵活,易学,易读,可移植并且功能强大。

高级

可以说,每一代编程语言的产生,我们都会达到一个新的高度。从汇编语言,到C Pascal等,伴随着C语言的诞生,产生了C++、Java这样的现代编译语言,之后有了强大的可以进行系统调用的解释性脚本语言Python、 Perl...
比如Python中就有一些高级的数据结构,列表和字典就是内建于语言本身可以直接使用的,在核心语言中提供这些重要的构建单元,可以缩短开发时间和代码量,产生可读性更好的代码。

面向对象

Python是面向对象编程

内存管理器

C 或者 C++最大的弊病在于内存管理是由开发者负责的。所以哪怕是对于一个很少访问、修改和管理内存的应用程序,程序员也必须在执行了基本任务之外履行这些职责。这些加诸在开发者身上的没有必要的负担和责任常常会分散精力。
Python 中,由于内存管理是由 Python 解释器负责的,所以开发人员就可以从内存事务中解放出来,全神贯注于最直接的目标,仅仅致力于开发计划中首要的应用程序。这会使错误更少、程序更健壮、开发周期更短。

解释性和编译性

Python 是一种解释型语言,这意味着开发过程中没有了编译这个环节。一般来说,由于不是以本地机器码运行,纯粹的解释型语言通常比编译型语言运行的慢。然而,类似于 Java,Python实际上是字节编译的,其结果就是可以生成一种近似机器语言的中间形式。这不仅改善了 Python的性能,还同时使它保持了解释型语言的优点。

通过这门课程的学习,我学到了python使用方法以及发展历史。学习到了函数编写,学习了面向对象编程。学习了异常文件处理,使得程序健壮性提高。学习了数据库,python如何操作数据库,对以后有着巨大的帮助最后学习了爬虫,学习到了流程控制语句学习到了序列如何应用、字符串与正则表达式如何实际去应用以及相关之间的关系以丰满程序的可读性和功能。

6. 课程感想体会:

老师教的很仔细,而且要求很高,mooc上的视频可以很好地巩固,包括做题啥的,都可以很好地贯彻,而且python是一门非常实用的课程,对于办公亦有着很大的用途,我希望能在以后进一步钻研并学习应用。

 

参考资料

 

posted @ 2020-06-06 22:38  20193309蔡毅敏  阅读(137)  评论(0编辑  收藏