面向对象
确实很多爬虫我们直接面向过程也可以解决
但是大家可能忘了一个问题:三大特性
面向对象来写的话,代码复用就能给我们省去很多时间了
面向过程和面向对象,以及切片编程,后面再给大家细说,下面就上模板啦
模板文件
写在前面
一个方法实现一个功能
注意区分形参
和实参
区分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()
评论区