Python爬虫抓取网页函数式编程

时间:2022-02-13 11:52:11 类型:python
字号:    

Python 函数式编程可以让程序的思路更加清晰、易懂

定义相应的函数,通过调用函数来执行爬虫程序

from urllib import request
from urllib import parse

# 拼接URL地址
def get_url(word):
url = 'http://www.baidu.com/s?{}'
#此处使用urlencode()进行编码
params = parse.urlencode({'wd':word})
url = url.format(params)
return url

# 发请求,保存本地文件
def request_url(url,filename):
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0'}
# 请求对象 + 响应对象 + 提取内容
req = request.Request(url=url,headers=headers)
res = request.urlopen(req)
html = res.read().decode('utf-8')
# 保存文件至本地
  with open(filename,'w',encoding='utf-8') as f:
    f.write(html)

# 主程序入口
if __name__ == '__main__':
word = input('请输入搜索内容:')
url = get_url(word)
filename = word + '.html'
request_url(url,filename)

下面以类的形式编写爬虫程序,并在类下编写不同的功能函数,代码如下所示:

from urllib import request,parse
import time
import random
from ua_info import ua_list #使用自定义的ua池

#定义一个爬虫类
class TiebaSpider(object):
#初始化url属性
def __init__(self):
self.url='http://tieba.baidu.com/f?{}'

# 1.请求函数,得到页面,传统三步
def get_html(self,url):
req=request.Request(url=url,headers={'User-Agent':random.choice(ua_list)})
res=request.urlopen(req)
#windows会存在乱码问题,需要使用 gbk解码,并使用ignore忽略不能处理的字节
#linux不会存在上述问题,可以直接使用decode('utf-8')解码
html=res.read().decode("gbk","ignore")
return html
# 2.解析函数,此处代码暂时省略,还没介绍解析模块
def parse_html(self):
pass
# 3.保存文件函数
def save_html(self,filename,html):
with open(filename,'w') as f:
f.write(html)
# 4.入口函数
def run(self):
name=input('输入贴吧名:')
begin=int(input('输入起始页:'))
stop=int(input('输入终止页:'))
# +1 操作保证能够取到整数
for page in range(begin,stop+1):
pn=(page-1)*50
params={
'kw':name,
'pn':str(pn)
}
#拼接URL地址   
params=parse.urlencode(params)
url=self.url.format(params)
#发请求
html=self.get_html(url)
#定义路径
filename='{}-{}页.html'.format(name,page)
self.save_html(filename,html)
#提示
print('第%d页抓取成功'%page)
#每爬取一个页面随机休眠1-2秒钟的时间
time.sleep(random.randint(1,2))
#以脚本的形式启动爬虫
if __name__=='__main__':
start=time.time()
spider=TiebaSpider() #实例化一个对象spider
spider.run() #调用入口函数
end=time.time()
#查看程序执行时间
print('执行时间:%.2f'%(end-start))  #爬虫执行时间

以面向对象方法编写爬虫程序时,思路简单、逻辑清楚,非常容易理解,上述代码主要包含了四个功能函数,它们分别负责了不同的功能,总结如下:

1) 请求函数

请求函数最终的结果是返回一个 HTML 对象,以方便后续的函数调用它。 

2) 解析函数

解析函数用来解析 HTML 页面,常用的解析模块有正则解析模块、bs4 解析模块。通过分析页面,提取出所需的数据,在后续内容会做详细介绍。

3) 保存数据函数

该函数负责将抓取下来的数据保至数据库中,比如 MySQL、MongoDB 等,或者将其保存为文件格式,比如 csv、txt、excel 等。

4) 入口函数

入口函数充当整个爬虫程序的桥梁,通过调用不同的功能函数,实现数据的最终抓取。入口函数的主要任务是组织数据,比如要搜索的贴吧名、编码 url 参数、拼接 url 地址、定义文件保存路径。

爬虫程序结构

用面向对象的方法编写爬虫程序时,逻辑结构较为固定,总结如下:

# 程序结构
class xxxSpider(object):
def __init__(self):
# 定义常用变量,比如url或计数变量等

def get_html(self):
# 获取响应内容函数,使用随机User-Agent

def parse_html(self):
# 使用正则表达式来解析页面,提取数据

def write_html(self):
# 将提取的数据按要求保存,csv、MySQL数据库等

def run(self):
# 主函数,用来控制整体逻辑

if __name__ == '__main__':
# 程序开始运行时间
spider = xxxSpider()
spider.run()

爬虫程序随机休眠

在入口函数代码中,包含了以下代码:

#每爬取一个页面随机休眠1-2秒钟的时间
time.sleep(random.randint(1,2))

爬虫程序访问网站会非常快,这与正常人类的点击行为非常不符。因此,通过随机休眠可以使爬虫程序模仿成人类的样子点击网站,从而让网站不易察觉是爬虫访问网站,但这样做的代价就是影响程序的执行效率

<