作者:vinyyu
声明:版权所有,转载请注明出处,谢谢。

1 调入需要使用的库

time库用于每次获取页面的时间间隔;pandas库用于DataFrame的数据格式存储;requests用于爬虫获取页面Html信息;BeautifulSoup用于去掉网页格式提取相关信息;lxml用于操作excel文件。
BeautifulSoup 目前已经被移植到 bs4 库中,也就是说在导入 BeautifulSoup 时需要先安装的是 bs4 库。

import time
import pandas as pd
import requests
from bs4 import BeautifulSoup
import lxml

2 用requests库获得已知网址的内容

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

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

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

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

2.1 用requests.get()获得页面内容

例如,需要获得网易体育的页面内容,编写最简单代码:

url='http://sports.163.com'
html = requests.get(url)
print(html.text)

获得结果如下:

可以看到,这里获得的是这个url的整个网页内容。然后我们需要通过所需内容的选择器(selector)和BeautifulSoup解析获得该网页中我们需要的部分内容。

2.2 获得页面中所需内容的选择器(selector)

*本文默认读者已知网页结构。网页一般由三部分组成,分别是 HTML(超文本标记语言)、CSS(层叠样式表)和JScript(活动脚本语言)。

推荐用Chrome浏览器打开网页。点击右上角“自定及管理”按钮,选择“更多工具”菜单,选择“开发人员工具”子菜单,打开网页开发平台。然后在一个网页的所需信息上,右键点击鼠标,弹出浮动菜单选择“检查”。在开发平台上选中的所需信息位置上,右键点击鼠标,弹出浮动菜单选择“Copy”,然后选择“copy selector”,复制所需页面的选择器。整个操作过程如下所示:


2.3 解析网页并获得选择器中的文本内容

下面代码第一句是用BeautifulSoup解析在2.1中通过requests.get()获得的html.txt。第二句是用BeautifulSoup的select()函数,参数是2.2中获得的选择器(selector),提取网页中我们需要的内容放到data变量中。for循环用于读取data中的内容并显示结果。
要明确BeautifulSoup的select()函数获得的data数据格式。提取的数据包含标题和链接,标题在<a>标签中,提取标签的正文用get_text() 方法。链接在<a>标签的 href 属性中,提取标签中的 href 属性用 get() 方法,在括号中指定要提取的属性数据,即 get(‘href’)。

soup=BeautifulSoup(html.text,'lxml')
data=soup.select('#index2016_wrap > div.index2016_content > div.clearfix.area.mb60 > div.col_con.clearfix > div.topnews > ul:nth-child(1) > li.tpn_first > h2 > a')
for item in data:result={'title':item.get_text(),'link':item.get('href')}print(result)

结果显示为:
如果我们需要获取所有的头条新闻,因此将 ul:nth-child(1)…中冒号(包含冒号)后面的部分删掉。并根据结果显示,可以采用字符串替换函数.replace("\n", " ")等清洗获得的数据。形成新的代码如下:

soup=BeautifulSoup(html.text,'lxml')
data=soup.select('#index2016_wrap > div.index2016_content > div.clearfix.area.mb60 > div.col_con.clearfix > div.topnews > ul')
for item in data:result={'title':item.get_text().replace('\n', ' '),'link':item.get('href')}print(result)

则所有结果显示为:

上面的程序只是用print语句看了一下结果,下面用pandas的DataFrame把数据保存起来

df_data=pd.DataFrame()
data=soup.select('#index2016_wrap > div.index2016_content > div.clearfix.area.mb60 > div.col_con.clearfix > div.topnews > ul')
for item in data:result={'title':item.get_text().replace('\n', ' '), 'link':item.get('href')}new=pd.DataFrame(result, index=[1])df_data=df_data.append(new,ignore_index=True)
df_data
df_data.to_excel("D:/result.xlsx", encoding='utf-8', index=False, header=True)

下图可以看到我们将整个结果保存到DataFrame数据框中,当然,也可以再对文本中“跟贴”的数量做字符串的处理提取等操作。最后,用lxml库中的to_excel()将结果保存到excel文件中。

3 用requests库获得多个网址的内容

例如有道翻译网站http://www.youdao.com,可以查询中文词语对应的英文表达。比如我们有一组词语“秋风送爽、琵琶行、筚路蓝缕、确实、过犹不及、海阔天空”,需要查询它们的意思,可以看到有道网站对应的网址为:
http://www.youdao.com/w/eng/中文词语/#keyfrom=dict2.index。
那么可以用循环构成同样类型的网页后获得对应词语的意思,语句如下。

array=['秋风送爽','琵琶行','筚路蓝缕','确实','过犹不及','海阔天空']
df_data=pd.DataFrame()
for item in array:url='http://www.youdao.com/w/eng/' + item + '/#keyfrom=dict2.index'html = requests.get(url)soup=BeautifulSoup(html.text,'lxml')data=soup.select('#phrsListTab > div.trans-container > ul > p > span:nth-child(1) > a')for subitem in data:result={'words':item,'title':subitem.get_text().replace('\n', ' '), 'link':subitem.get('href')}new=pd.DataFrame(result, index=[1])df_data=df_data.append(new,ignore_index=True)
df_data.to_excel("D:/result1.xlsx", encoding='utf-8', index=False, header=True)

需要查找的中文词语做成列表,然后建立一个存放检索结果的DataFrame。循环选择每个词语构成对应网页,用requests库的get()函数获得网页内容,然后用BeautifulSoup解析该网页。用前2.2中所述方法获得对应翻译的selector,并通过select()函数获得对应内容。再通过一个循环将提取标题和链接对应数据,每次提取后建立一个新的DataFrame名称为new,然后添加到存放检索结果的df_data当中去。获得的df_data结果如下。最后同样的,用lxml库中的to_excel()将结果保存到excel文件中。

4 批量抓取的反爬策略

爬虫是模拟人的浏览访问行为,进行数据的批量抓取。当抓取的数据量逐渐增大时,会给被访问的服务器造成很大的压力,甚至有可能崩溃。换句话就是说,服务器是不喜欢有人抓取自己的数据的。那么,网站方面就会针对这些爬虫者,采取一些反爬策略。服务器第一种识别爬虫的方式就是通过检查连接的 useragent 来识别到底是浏览器访问,还是代码访问的。如果是代码访问的话,访问量增大时,服务器会直接封掉来访 IP。
那么应对这种初级的反爬机制,我们可以采用两种简单策略应对。一是构造浏览器的请求头,封装自己的请求;二是增加抓取数据的时间间隔。

4.1 构造浏览器请求

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

headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18363'}
html = requests.get(url, headers=headers)

这个headers必须是自己所用浏览器信息。获得的方法是,首先用chrome浏览器浏览一个网页,然后打开“开发者工具”,在“network”页面中选择“All”标签。
左边“Name”列表栏中很多个随便选一栏点击后,可以看到右边“Headers”栏。在该栏目下找到“User-Agent”,其后面的内容就是requests.get的headers参数的值。具体如下图所示。

4.2 增加时间间隔

就是常用的增设延时,例如每 1秒钟抓取一次,代码如下:

time.sleep(1)

5 异常处理

爬虫异常会在没有网络连接(没有路由到特定服务器),或者服务器不存在的情况下产生。但在正常情况下,多次重复的请求也可能网站响应缓慢而捕捉不到所需内容。当我们保证网站链接和服务器是正常的情况下,可以捕捉异常并再次请求的方法保证对网站的爬取。基本代码如下:

i = 0
while i < 10:try:html = requests.get(url, timeout=5, headers=headers)return htmlexcept requests.exceptions.RequestException:i += 1print(i)

requests库中get()函数的timeout 参数,包括:

  1. 连接(connet)超时 指的是客户端实现到远端服务器端口的连接时request 所等待的时间。连接超时一般设为比 3 的倍数略大的一个数值,因为 TCP 数据包重传窗口的默认大小是 3。

  2. 读取(read)超时 指的客户端已经连接上服务器并且发送了request后,客户端等待服务器发送请求的时间。

timeout 可以设置一个元组,也可以象上述例程一样设置单一的值,将会用作 connect 和 read 二者的 timeout。

如果发生响应超时的情况,则异常代码为requests.exceptions.RequestException,这时异常处理次数增加1次。重复请求网页,直到累计10次错误后退出循环。

6 完整的小爬虫

仍然以有道翻译中文词语为例,实现了反爬虫和异常处理的完整小程序如下:

headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18363'}
def gethtml(url, headers):i = 0while i < 10:try:html = requests.get(url, timeout=5, headers=headers)return htmlexcept requests.exceptions.RequestException:i += 1print(i)array=['秋风送爽','琵琶行','筚路蓝缕','确实','过犹不及','海阔天空']
df_data=pd.DataFrame()
for item in array:url='http://www.youdao.com/w/eng/' + item + '/#keyfrom=dict2.index'html = gethtml(url,headers)time.sleep(1)soup=BeautifulSoup(html.text,'lxml')data=soup.select('#phrsListTab > div.trans-container > ul > p > span:nth-child(1) > a')for subitem in data:result={'words':item,'title':subitem.get_text().replace('\n', ' '), 'link':subitem.get('href')}new=pd.DataFrame(result, index=[1])df_data=df_data.append(new,ignore_index=True)
df_data.to_excel("D:/result1.xlsx", encoding='utf-8', index=False, header=True)

总结

本文实现了完整的python小爬虫。具体网页的selector要根据自己所需内容确定;get()获取网页的Headers参数也要根据自己的电脑条件填写;最终获得的数据还应该根据自己的需求继续处理,本文当中仅做了最简单处理。
另外,这个是requests库中get()方式获得网页,另外一种requests库中的post()方式获得网页在别的篇幅中再做介绍。

简单完整的Python小爬虫教程相关推荐

  1. python课程开课吧怎么样-廖雪峰总结的Python商业爬虫教程,请查收!

    原标题:廖雪峰总结的Python商业爬虫教程,请查收! 2018 IEEE最热门48种编程语言榜,Python雄踞四项第一! 据介绍,IEEE Spectrum 的排序是综合 10 个精选线上数据源, ...

  2. python小爬虫之天气查询

    python小爬虫之天气查询 刚开始研究爬虫,这个小程序通过抓取网页源代码,使用json解析实现了天气的查询. 1.需求分析 该博客实现了简单的天气查询功能,输入城市名称后可以查询出该城市的天气情况. ...

  3. python网络爬虫教程(四):强大便捷的请求库requests详解与编程实战

    上一章中,我们了解了urllib的基本用法,详情可浏览如下链接python网络爬虫教程(三):详解urllib库,但其中确实有不方便的地方,为此,我们可以使用更方便更简洁的HTTP请求库request ...

  4. python小爬虫SendKey自动刷博刷视频外挂

    python小爬虫SendKey自动刷博刷视频 SendKeys简介 sendkeys是python的一个扩展包,其中有一些常用的符号来表示键盘的快捷键或者输入的字符,对于pywinauto来说,非常 ...

  5. python批量下载网页文件-超简单超详细python小文件、大文件、批量下载教程

    按照不同的情况,python下载文件可以分为三种: 小文件下载 大文件下载 批量下载 python 小文件下载 流程:使用request.get请求链接,返回的内容放置到变量r中,然后将r写入到你想放 ...

  6. python批量下载文件教程_超简单超详细python小文件、大文件、批量下载教程

    按照不同的情况,python下载文件可以分为三种: 小文件下载 大文件下载 批量下载 python 小文件下载 流程:使用request.get请求链接,返回的内容放置到变量r中,然后将r写入到你想放 ...

  7. python网络爬虫教程-教你从零开始学会写 Python 爬虫

    原标题:教你从零开始学会写 Python 爬虫 写爬虫总是非常吸引IT学习者,毕竟光听起来就很酷炫极客,我也知道很多人学完基础知识之后,第一个项目开发就是自己写一个爬虫玩玩. 其实懂了之后,写个爬虫脚 ...

  8. python网络爬虫教程-如何入门 Python 爬虫?

    "入门"是良好的动机,但是可能作用缓慢.如果你手里或者脑子里有一个项目,那么实践起来你会被目标驱动,而不会像学习模块一样慢慢学习. 另外如果说知识体系里的每一个知识点是图里的点,依 ...

  9. python网络爬虫教程-终于明了python网络爬虫从入门到实践

    Python是一款功能强大的脚本语言,具有丰富和强大的库,重要的是,它还具有很强的可读性,易用易学,非常适合编程初学者入门.以下是小编为你整理的python网络爬虫从入门到实践 环境配置:下载Pyth ...

最新文章

  1. JAVA中栈和堆总结
  2. cmd安装pip_离线情况下怎么安装numpy、pandas和matplotlib?一步一步教你
  3. 6.exit _exit _Exit
  4. Mybatis缓存配置
  5. 准备离职,工作的一些细节记录
  6. 韩顺平 java笔记 第3讲 运算符 流程控制
  7. Sequence I
  8. 方法冲突_化解冲突,要避免用这 2 种方法
  9. 手机安装 Linux 系统教程
  10. 非法本法考备考经验总结
  11. Deeper引领WEB3.0世界:去中心化、 安全性和超高速率的统一
  12. built a JNCIS LAB系列:Chapter 7 MPLS
  13. 使用VLC把视频转换为一帧一帧的图片
  14. 由微博图床挂掉之后想到的
  15. cesium 学习笔记(三) 在地图上放置3D建筑模型
  16. 浅谈当下火热的ChatGPT
  17. 基于卷积神经网络的句子分类模型【经典卷积分类附源码链接】
  18. 根据特征重要性进行特征选择
  19. 切割绳子问题(附 java 代码)
  20. Easy3DCGAL 点云下采样(体素)

热门文章

  1. Ubuntu中类似QQ截图的截图工具并实现鼠标右键菜单截图
  2. 理解Android Framework
  3. RGB图像任意角度旋转
  4. Wpf之无法获取鼠标点击事件
  5. wpf之lable右下角放关闭图标
  6. RTCP协议解析--RR
  7. 如何在浏览器中显示本地文件系统_如何完全卸载浏览器中的Flash插件
  8. python 与_Python基础 第一个 Python 程序
  9. jquery audio没有声音_Audio-technica 铁三角 ATH-DSR7BT 头戴式蓝牙无线耳机测评报告 [Soomal]...
  10. springboot+activiti工作流mybatis冲突解决办法