面向对象
- 确实很多爬虫我们直接面向过程也可以解决
- 但是大家可能忘了一个问题:
三大特性
- 面向对象来写的话,代码复用就能给我们省去很多时间了
- 面向过程和面向对象,以及切片编程,后面再给大家细说,下面就上模板啦
模板文件
写在前面
一个方法实现一个功能
- 注意区分
形参
和实参
- 区分
yield
和列表推导式
- 解析函数方法很多:
xpath
、beautifulsoup4
、正则表达式
…
- 记得处理
返回值None
- 不同情况使用不同的
调用方式
初始化方法
- 定义当前类里面用到的变量
- 未知参数在具体函数中使用
.format(参数)
替换(%s也可以,推荐.format())
import requests
from lxml import etree
class Template():
def __init__(self):
"""
初始化变量
"""
self.base_url = "https://123123/list/020000,000000,0000,00,9,99,2,{}.html?"
self.headers = {}
获取URL列表
- 可以生成器,亦可以使用列表推导式
- 生成器:一个一个返回,数据生成时间较长时使用比较好用
- 列表推导式:处理完所有数据再返回,数据生成时间短时比较好用
def get_url_list(self):
"""
通过base_url获取URL的列表
:return: 通过base_url获取到的url_list
"""
# 1. 使用yield返回数据
for page in range(1, 100):
url = self.base_url.format(page)
yield url
# 2. 使用列表推导式
return [self.base_url.format(page) for page in range(1, 100)]
获取网页源码
- 这里是获取网页源码,对于Ajax请求直接返回数据的注意返回值
- 注意
状态码
、编码
、返回的是html
def get_url_html(self, url):
"""
获取当前url的html
:param url: 需要抓取的url
:return: 当前url的html
"""
response = requests.get(url, headers=self.headers)
if response.status_code == 200:
response.encoding = response.apparent_encoding # 指定编码
return response.text
return None
解析网页源码
- 拿到网页源码之后,在这里解析,可用的方法比较多,大家自行选择
- 就像上面提到的,这里就比较适合用
yield
返回
def parse_html(self, html):
"""
解析当前html
:param html: 需要解析的html文本
:return: 当前html中的数据
"""
x_html = etree.HTML(html)
items = x_html.xpath("") # xpath/
for item in items:
yield item
处理结果数据
- 记住一个方法只做一件事,这里我们
只保存一个数据
- 这与面向过程有点区别,面向过程的时候,这里可能就要处理上一个函数返回的列表了
- 一样,存文本、存SQL(MySQL、MongoDB),或者再处理都是可以的
def parse_item(self, item):
"""
处理结果:文本,SQL,print...
:param item: 需要处理的数据
:return: 当前数据的处理结果
"""
print(item)
入口函数
- 这里就编写整个处理流程就可以了
- 上面没有做的一些事在这里就可以操作了
- 如果想把入口函数写的简洁,把这里的
if
、for
放到函数里就可以了
def run(self):
for url in self.get_url_list():
html = self.get_url_html(url)
if html == None:
continue
for item in self.parse_html(html):
if item == None:
continue
self.parse_item(item)
调用
- 这里是直接实例化一个对象,然后调用它的方法
- 如果在其他情况调用,酌情选择调用方式
template = Template()
template.run()
评论区