根据我的经验,我没有做太多的网页抓取。到目前为止,我正在使用python并使用BeautifulSoup4
来抓取hackernews页面。
只是想知道在进行刮擦之前是否应该记住模式。现在代码看起来非常难看,我觉得自己像个黑客。
代码:
import requests
from bs4 import BeautifulSoup
class Command(BaseCommand):
page = {}
td_count = 2
data_count = 0
def handle(self, *args, **options):
for i in range(1,4):
self.page_no = i
self.parse()
print self.page[1]
def get_result(self):
return requests.get('https://news.ycombinator.com/news?p=%s'% self.page_no)
def parse(self):
soup = BeautifulSoup(self.get_result().text, 'html.parser')
for x in soup.find_all('table')[2].find_all('tr'):
self.data_count += 1
self.page[self.data_count] = {'other_data' : None, 'url' : ''}
if self.td_count%3 == 0:
try:
subtext = x.find_all('td','subtext')[0]
self.page[self.data_count - 1]['other_data'] = subtext
except IndexError:
pass
title = x.find_all('td', 'title')
if title:
try:
self.page[self.data_count]['url'] = title[1].a
print title[1].a
except IndexError:
print 'Done page %s'%self.page_no
self.td_count +=1
答案 0 :(得分:3)
实际上,我将可抓取数据作为我的域(业务)数据的一部分,这使我可以使用域驱动设计来解决问题:
实体和价值对象
我使用实体和值对象将正确提取的信息从数据存储到我的编程语言数据结构中,因此我可以很好地使用它们。
存储库模式
我使用存储库模式将收集数据的工作委托给另一个类。存储库类被赋予一个站点,然后获取数据并在需要时预构建实体。
Transformer / Presenter pattern
从存储库中获取数据后,我将html数据传递给presenter类。演示者类有责任从给定的HTML字符串创建业务实体/值对象。
服务层
如果有比上述更多的进程,我创建一个服务类,它是问题的包装器,它调用存储库,将提取的数据提供给演示者,演示者构建实体,并完成,结果可能被另一个服务用于存储在SQL数据库中。
如果您熟悉PHP,我已经在Laravel编写了一个小应用程序,每15分钟获取一个给定网站的alexa排名,并通过电子邮件通知该网站的订阅者。