数据技术|十分钟教会你写网络爬虫程序

写在前面

临近双11,小伙伴们都开始忙着剁手了。蛋是,这个学习还是不能落下的。那么,今天小编又给大家带来什么好玩的玩意儿呢?

那自然是

神奇&&牛掰

爬虫技术

在互联网时代,爬虫绝对是一项非常有用的技能。借助它,你可以快速获取大量的数据并自动分析,或者帮你完成大量重复、费时的工作,分分钟成为掌控互联网的大师。

注意:欲获取本文所涉及的文案,代码及教学视频的链接,请移步留言区。这是我们第一次录制教学视频来帮助大家更好的学习技术,该视频的录制耗时超过八个小时。

什么是爬虫?

-- 爬虫,即网络爬虫,大家可以理解为在网络上爬行的一只蜘蛛,互联网就比作一张大网,而爬虫便是在这张网上爬来爬去的蜘蛛咯,如果它遇到资源,那么它就会抓取下来。想抓取什么?这个由你来控制。

-- 比如它在抓取一个网页,在这个网中他发现了一条道路,其实就是指向网页的超链接,那么它就可以爬到另一张网上来获取数据。这样,整个连在一起的大网对这之蜘蛛来说触手可及,分分钟爬下来不是事儿。 -- 在用户浏览网页的过程中,我们可能会看到许多好看的图片,比如

,我们会看到几张的图片以及百度搜索框,这个过程其实就是用户输入网址之后,经过DNS服务器,找到服务器主机,向服务器发出一个请求,服务器经过解析之后,发送给用户的浏览器 HTML、JS、CSS 等文件,浏览器解析出来,用户便可以看到形形色色的图片了。

-- 因此,用户看到的网页实质是由 HTML 代码构成的,爬虫爬来的便是这些内容,通过分析和过滤些 HTML 代码,实现对图片、文字等资源的获取。

那URL又是什么呢?

-- URL,即统一资源定位符,也就是我们说的网址,统一资源定位符是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。

-- URL的格式由三部分组成:

1是协议(或称为服务方式)。

2是存有该资源的主机IP地址(有时也包括端口号)。

3是主机资源的具体地址,如目录和文件名等。

爬虫爬取数据时必须要有一个目标的URL才可以获取数据,因此,它是爬虫获取数据的基本依据,准确理解它的含义对爬虫学习有很大帮助。

看完了上面的介绍,小伙伴们是不是已经迫不及待想要搞搞事情了呢?

下面正式为你们介绍如何利用爬虫获取资源

①环境配置

学习Python,当然少不了环境的配置。要使用python进行各种开发和科学计算,还需要安装对应的包。在这里给大家推荐Anaconda它把需要的包都集成在了一起,因此我们实际上从头到尾只需要安装Anaconda软件就行了,而且Anaconda自带编译器spyder。下载地址:

下载安装包名称为:Anaconda3-5.0.0-Windows-x86_64.exe

按照正常步骤安装即可,

注意事项

将两个选项都选上,将安装路径写入环境变量 然后等待安装完成就行了。

如何管理python包?

安装一个包:

conda install package_name

移除一个包:

conda remove package_name

升级包版本:

conda update package_name

查看所有的包:

conda list

这样就可以将包安装进Anaconda里面,如果你要想把包安装进自己的系统里面的话就用pip命令了。

安装完Anaconda后,我们就可以用自带的spyder编译器来写代码了。

好了,环境配置好了。接下来跟着小编的步伐一起来搞点事情吧。

②确定URL并抓取页面代码

糗事百科大家都听说过吧?糗友们发的搞笑的段子一抓一大把,现在我们尝试抓取一下糗事百科的热门段子吧,每按下一次回车我们显示一个段子。

首先我们确定好页面的URL是

其中最后一个数字1代表页数,我们可以传入不同的值来获得某一页的段子内容。我们初步构建如下的代码来打印页面代码内容试试看,先构造最基本的页面抓取方式。

import urllib
import urllib.request
page = 1
user_agent = 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:56.0) 
Gecko/20100101 Firefox/56.0'
//模拟浏览器的头
headers = { 'User-Agent' : user_agent }
try:
    request = urllib.request.Request(url,headers = headers)
    response = urllib.request.urlopen(request)
    print(response.read())
except urllib.request.URLError, e:
    if hasattr(e,"code"):
        print(e.code)
    if hasattr(e,"reason"):
        print(e.reason)

③提取某一页的所有段子

进入糗事百科的界面,我们打开浏览器自带的WEB查看器

我们可以看到,每一个段子都是<div class=”article block untagged mb15″ id=”…”>…</div>包裹的内容。

现在我们想获取发布人,发布日期,段子内容,以及点赞的个数。不过另外注意的是,段子有些是带图片的,如果我们想在控制台显示图片是不现实的,所以我们直接把带有图片的段子给它剔除掉,只保存仅含文本的段子。

所以我们加入如下正则表达式来匹配一下,用到的方法是 re.findall 是找寻所有匹配的内容。

content = response.read().decode('utf-8')

//已经爬取的网页内容

pattern = re.compile('<div.*?author">.*?<a.*?<img.*?>(.*?)</a>.*?<div.*?'+

'content">(.*?)<!--(.*?)-->.*?</div>(.*?)<divclass="stats.*?class="number">(.*?)</i>',re.S)

items = re.findall(pattern,content)

for item in items:

print(item[0],item[1],item[2],item[3],item[4])

现在正则表达式在这里稍作说明

1).*? 是一个固定的搭配,.和*代表可以匹配任意无限多个字符,加上?表示使用非贪婪模式进行匹配,也就是我们会尽可能短地做匹配,以后我们还会大量用到 .*? 的搭配。

2)(.*?)代表一个分组,在这个正则表达式中我们匹配了五个分组,在后面的遍历item中,item[0]就代表第一个(.*?)所指代的内容,item[1]就代表第二个(.*?)所指代的内容,以此类推。

3)re.S 标志代表在匹配时为点任意匹配模式,点 . 也可以代表换行符。这样我们就获取了发布人,发布时间,发布内容,附加图片以及点赞数。

在这里注意一下,我们要获取的内容如果是带有图片,直接输出出来比较繁琐,所以这里我们只获取不带图片的段子就好了。在这里我们就需要对带图片的段子进行过滤。

我们可以发现,带有图片的段子会带有类似下面的代码,而不带图片的则没有,我们的正则表达式的item[3]就是获取了下面的内容,如果不带图片,item[3]获取的内容便是空。

所以我们只需要判断item[3]中是否含有img标签就可以了。

我们再把上述代码中的for循环改为下面的样子

for item in items:

haveImg = re.search("img",item[3])

if not haveImg:

print(item[0],item[1],item[2],item[4])

4. 完善交互,设计面向对象模式

现在最核心的部分我们已经完成啦,剩下的就是修一下边边角角的东西,我们想达到的目的是:

按下回车,读取一个段子,显示出段子的发布人,发布日期,内容以及点赞个数。

另外我们需要设计面向对象模式,引入类和方法,将代码做一下优化和封装,最后,我们的代码如下所示:

import urllib.request  
import re    
import _thread    
import time       //调用的包
#----------- 加载处理糗事百科 -----------    
class Spider_Model:    
    def __init__(self):    
        self.page = 1    
        self.pages = []    
        self.enable = False    
    # 将所有的段子都扣出来,添加到列表中并且返回列表    

# 用于加载新的段子

def LoadPage(self):

# 如果用户未输入quit则一直运行

while self.enable:

# 如果pages数组中的内容小于2个

if len(self.pages) < 2:

try:

# 获取新的页面中的段子们

myPage = self.GetPage(str(self.page))

self.page += 1

self.pages.append(myPage)

except:

print ('无法链接糗事百科!' )

else:

time.sleep(1)

def ShowPage(self,nowPage,page):

for items in nowPage:

print (" ", items)

myInput = input()

if myInput == "quit":

self.enable = False

break

def Start(self):

self.enable = True

page = self.page

print(page)

print (u'正在加载中请稍候......')

# 新建一个线程在后台加载段子并存储

_thread.start_new_thread(self.LoadPage,())

#----------- 加载处理糗事百科 -----------

while self.enable:

# 如果self的page数组中存有元素

if self.pages:

nowPage = self.pages[0]

del self.pages[0]

self.ShowPage(nowPage,page)

page += 1

#----------- 程序的入口处 -----------

print (u"""

---------------------------------------

程序:糗百爬虫

日期:2017-10-23

语言:Python 3.5.2

操作:输入quit退出阅读糗事百科

功能:按下回车依次浏览今日的糗百热点

---------------------------------------

""")

print( u'请按下回车浏览今日的糗百内容:' )

input(' ')

myModel = Spider_Model()

myModel.Start()

效果展示

来看看我们的程序的演示效果吧

自从有了这个爬虫以后,层出不穷的段子供你欣赏哦!

而且大家还可以根据自己喜好把段子输出成文件或者把程序打包成exe文件,具体的做法会在以后给出。

1

END

原文发布于微信公众号 - 数据魔术师(gh_39567a079597)

原文发表时间:2017-11-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏企鹅号快讯

Python爬虫:selenium的填坑心得

在之前的文章中说过,模拟浏览器在现在的python库中有两个选择Mechanize与Selenium:然而Mechanize不支持JavaScript,Sele...

7419
来自专栏王清培的专栏

alibaba druid 在springboot start autoconfig 下的bug

标签(空格分隔):druid springboot start autoconfig

1490
来自专栏FreeBuf

用搜索神器Everything定位Webshell木马后门

Everything是速度最快的文件名搜索软件。其速度之快令人震惊,百G硬盘几十万个文件,可以在几秒钟之内完成索引;文件名搜索瞬间呈现结果。它小巧免费,支持中文...

2798
来自专栏互联网开发者交流社区

Redis简介

1632
来自专栏北京马哥教育

通过IP获取地理位置信息的几种方式

1、QQWry IP纯真数据库 纯真版IP地址数据库是当前网络上最权威、地址最精确、IP记录以及网吧数据最多的IP地址数据库。收集了包括中国电信、中国移动、中...

5385
来自专栏PHP在线

2018最新PHP学习路线整合

PHP是一种通用开源脚本语言。语法吸收了C语言、Java和Perl的特点,利于学习,使用广泛,主要适用于Web开发领域。

3485
来自专栏ytkah

微信公众平台开放JS-SDK(微信内网页开发工具包)

微信公众平台开放JS-SDK(微信内网页开发工具包),这次开放接口是质的飞跃,是对开发者和广大用户一个利好的消息。未来的公众号图文消息会更丰富多彩,准备脑洞大开...

3.7K6
来自专栏落影的专栏

iOS电商类APP的研发

前言 本文是研发一个在线超市的电商类APP过程中,对架构的整理。 ? 功能: 1、浏览商品、购买商品、切换商店; 2、查看订单、订单投诉、意见反馈; 3、...

76110
来自专栏云计算

JClouds的命令行界面

我已经使用jclouds一年多了,也一直为它的进步做贡献。目前为止,我已经在很多领域广泛地使用它,特别是在 Fuse Ecosystem 。总之,它是一个特别棒...

2507
来自专栏PHP在线

建立灵巧结构的PHP程序

很早就想写这篇文章了,但一直没有时间完成它。不是说我来告诉大家如何做,我更希望本文只是做为一个引子,与大家来讨论关于如何建立一个有效地、灵活的网络应用程序。 ...

3036

扫码关注云+社区

领取腾讯云代金券