Так и нужен скрипт который будет проверять на консистентность.
У меня есть похожий скрипт, но он на C#
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using DynamicPluginData;
using System.Text.RegularExpressions;
using System.Reflection;
using System.Collections.Specialized;
using System.IO;
using LowLevel;
using System.Net;
using System.Threading;
using System.Collections;
using HtmlAgilityPack;
namespace DatacolDynamicPluginNS
{
public class DynamicPluginClass
{
public static DataTable preExportData(DataTable dataTable, ItemInfo itemInfo, GlobalInfo globalInfo)
{
//Название поля данных, в которое собрана таблица характеристик
string FieldName = "Характеристики";
//Список Xpath выражений для сохранения области, в которой находится название и значение одной характеристики
List<string> ParameterAreaXpathList = new List<string> {"//li"};
//Список Xpath выражений для сохранения названия характеристики из вырезанной области
List<string> ParameterNameXpathList = new List<string> {"//div[1]"};
//Список Xpath выражений для сохранения значения характеристики из вырезанной области
List<string> ParameterValueXpathList = new List<string> {"//div[2]"};
//Список регулярных выражений для сохранения области, в которой находится название и значение одной характеристики
List<string> ParameterAreaRegexList = new List<string> ();//{"<dl[^<>]*?product-spec[^<>]*?>.*?</dl>"}
//Список регулярных выражений для сохранения названия характеристики из вырезанной области
List<string> ParameterNameRegexList = new List<string> ();//{"<span[^<>]*?product-spec__name-inner[^<>]*?>(.*?)<.*?>"}
//Список регулярных выражений для сохранения значения характеристики из вырезанной области
List<string> ParameterValueRegexList = new List<string> ();//{"<span[^<>]*?product-spec__value-inner[^<>]*?>(.*?)<.*?>"}
bool AreasFound = false;
bool TitlesFound = false;
DataTable tempDT = new DataTable();
for (int i = 0; i < dataTable.Rows.Count; i++)
{
List<string> Areas = getMatches(dataTable.Rows[i][FieldName].ToString(), ParameterAreaXpathList, ParameterAreaRegexList);
if (Areas.Count == 0) continue;
AreasFound = true;
foreach (string Area in Areas)
{
string Title = getMatch(Area, ParameterNameXpathList, ParameterNameRegexList, 1, true);
if (Title == "") continue;
TitlesFound = true;
if (!dataTable.Columns.Contains(Title))
{
dataTable.Columns.Add(Title);
}
}
}
if (!AreasFound) throw new Exception("Области с характеристиками не найдены");
if (!TitlesFound) throw new Exception("Названия характеристик не найдены");
DataTable tempDT2 = new DataTable();
bool ValuesFound = false;
for (int i = 0; i < dataTable.Rows.Count; i++)
{
#region Get characteristics
List<string> Areas = getMatches(dataTable.Rows[i][FieldName].ToString(), ParameterAreaXpathList, ParameterAreaRegexList);
if (Areas.Count == 0) continue;
foreach (string Area in Areas)
{
string Title = getMatch(Area, ParameterNameXpathList, ParameterNameRegexList, 1, true);
if (Title == "") continue;
string Value = getMatch(Area, ParameterValueXpathList, ParameterValueRegexList, 1, true);
if (String.IsNullOrEmpty(Value)) continue;
ValuesFound = true;
dataTable.Rows[i][Title] = Value;
}
#endregion
}
if (!ValuesFound) throw new Exception("Значения характеристик не найдены");
return dataTable;
}
/// <summary>
/// Получаем список участков
/// </summary>
/// <param name="DataTable"></param>
/// <param name="ParameterAreaXpathList"></param>
/// <param name="ParameterAreaRegexList"></param>
public static List<string> getMatches(string RawParameterSource, List<string> ParameterAreaXpathList, List<string> ParameterAreaRegexList, int RegexGroup = 0, bool StripTags = false)
{
List<string> RetVal = new List<string>();
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(RawParameterSource);
HtmlDocument docin = new HtmlDocument();
//Поиск по xpath
foreach (string xpath in ParameterAreaXpathList)
{
if (doc.DocumentNode.SelectNodes(xpath) == null) continue;
foreach (HtmlNode node in doc.DocumentNode.SelectNodes(xpath))
{
RetVal.Add(node.OuterHtml);
}
}
//Поиск по regex
foreach (string regex in ParameterAreaRegexList)
{
MatchCollection matches = Regex.Matches(RawParameterSource, regex, RegexOptions.Singleline | RegexOptions.IgnoreCase);
foreach (Match match in matches)
{
RetVal.Add(match.Groups[RegexGroup].ToString());
}
}
if (StripTags)
{
for (int i = 0; i < RetVal.Count; i++)
{
RetVal[i] = extra.strip_tags(RetVal[i]).Trim();
}
}
return RetVal;
}
public static string getMatch(string RawParameterSource, List<string> ParameterAreaXpathList, List<string> ParameterAreaRegexList, int RegexGroup = 0, bool StripTags = false)
{
List<string> RetValList = getMatches(RawParameterSource, ParameterAreaXpathList, ParameterAreaRegexList,
RegexGroup,
StripTags);
if (RetValList.Count == 0) return "";
return RetValList[0];
}
}
}
Но не я его писал и не смогу повторить на Питоне ) Думал что есть уже какое то готовое решение на Scrapy.