1、插入并获取网页数据
为了对已经写好的代码进行测试,我们先使用测试数据来看流程是否通过,假设对于一个网站有以下两个页面,且页面中含有一些内容(将这两个网页存在本地服务器下):
URL:http://localhost/DIPRE/BestSeller.html
URL:http://localhost/DIPRE/TopRated.html
首先我们将这两个URL存入数据库里的webpage表中(但注意为了模式的特异性,形成模式时要先去掉http://或https://的开头,后面会再提到),然后利用python先从数据库中获取所有webpage表中的字段(这里就一个字符串字段:url),再利用爬虫获取到这所有url中body的内容作为我们的源数据:
import requests
from bs4 import BeautifulSoup
def CrawlWeb(path): # 利用爬虫获取URL中body的内容:
html = requests.get(path)
soup = BeautifulSoup(html.text)
body = soup.body
return str(body) # 这里一定要注意转化成字符串,不然返回的是soup对象
def GetData(): # 获取数据库中的数据,以列表—字典的形式返回
cursor = db.cursor()
sql = "select * from webpage"
data = []
try:
cursor.execute(sql)
results = cursor.fetchall()
for row in results:
each = {}
each['id'] = row[0]
each['text'] = CrawlWeb(row[1])
each['url'] = row[1].lstrip('http://').lstrip('https://') # 截取掉http后获取URL
data.append(each)
except:
db.rollback()
cursor.close()
return data
data = GetData()
data
2、插入并获取初始种子
我们有了源数据之后,需要手动输入一些种子,在这个测试用例中至少需要来自同一个页面的两个种子才能形成一个模式,我们选择(Ernest Miller Hemingway,The Old Man and the Sea)和(W. William Shakespeare,A Midsummer Night's Dream)这两个元组对,因为这两个元组在BestSeller.html同时存在,方便我们形成模式。
由此在数据库中创建seeds表,加入author和title两个字段,并存入以上两个元组对,同时利用python获取seeds表中的数据:
def GetSeeds():
cursor = db.cursor()
sql = "select * from seeds"
seeds = []
try:
cursor.execute(sql)
results = cursor.fetchall()
for row in results:
each = {}
each['id'] = row[0]
each['author'] = row[1]
each['title'] = row[2]
seeds.append(each)
except:
db.rollback()
cursor.close()
return seeds
seeds = GetSeeds()
seeds
3、在网页数据中搜索种子并记录成事件
获取到seeds数据后,我们先写个记录事件的函数,用以记录一个种子在一个页面中出现的事件结构:
def SearchSeedInPage(author,title,url,line): # 在文章中搜索一个种子的元组对并记录事件
occurrence = {}
if author in line and title in line: # 作者和标题都在该行则记录事件,需要先判定是作者在前还是标题在前
posA = line.index(author)
posT = line.index(title)
if(posA<posT): # 如果作者在前则为1,否则为0
order = 1
if posA-CONST_M>=0:
prefix = line[posA-CONST_M:posA] # 记录author前m个字符作为前缀
else:
prefix = line[:posA] # 如果前m个字符超出下界则m记为0
middle = line[posA+len(author):posT]
suffix = line[posT+len(title):posT+len(title)+CONST_M] # 记录title后m个字符作为后缀,后界不用if,因为默认超出len按len计算
else:
order = 0
if posT-CONST_M>=0:
prefix = line[posT-CONST_M:posT]
else:
prefix = line[:posT]
middle