automated Pipeline for parsing profiles of politically exposed persons (PEP) into Wikidata
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

120 lines
4.5 KiB

import yaml
import json
import urllib.request, urllib.error, urllib.parse
from lxml import etree
import lxml.html
import lxml.html.soupparser
class membersParliamentCrawler(object):
def __init__(self, configFile):
with open(configFile, "r") as stream:
try:
self.config = yaml.safe_load(stream)
except yaml.YAMLError as exc:
print(exc)
# input list of countries in form of ['nicaragua', 'honduras', .. , 'mexico']
def downloadMemberListPagesOfCountries(self, listOfCountries):
# download only html pages of the countries specified in input
for country in listOfCountries:
for key in self.config:
if key in listOfCountries:
try:
memberList = self.config.get(key).get('memberList')
except Exception as e:
print("There is a problem with the entry memberList in the config.yaml - the original error message is:", e)
try:
memberListLink = memberList.get('link')
except Exception as e:
print("No memberListLink defined in config.yaml - the original error message is:", e)
# download the html page of the List of Members
response = urllib.request.urlopen(memberListLink)
webContent = response.read().decode('UTF-8')
# save interim results to files
f = open('pages/' + key +'MemberList.html', 'w+')
f.write(webContent)
f.close
def parseMemberListData2dictionary(self, listOfCountries):
for country in listOfCountries:
try:
#use soupparser to handle broken html
tree = lxml.html.soupparser.parse('pages/' + country + 'MemberList.html')
# for e in tree.iter():
#
# print(e.tag)
#
# for e in tree.xpath('//html//body//form//table//tr//td//table//tr'):
#
# #print(etree.tostring(e).decode())
dictionaryMemberList = {}
countryConf = self.config.get(country)
countryConfMemberList = countryConf.get('memberList')
countryConfMemberListParent = countryConfMemberList.get('parent')
countryConfMemberListChildName = countryConfMemberList.get('child-name')
countryConfMemberListChildLink = countryConfMemberList.get('child-link')
for n in range(len(tree.xpath(countryConfMemberListParent))):
name = tree.xpath(countryConfMemberListParent + '[' + str(n) + ']' + countryConfMemberListChildName)
link = tree.xpath(countryConfMemberListParent + '[' + str(n) + ']' + countryConfMemberListChildLink)
if len(name) > 0:
dictionaryMemberList[name[0]] = {}
dictionaryMemberList[name[0]]['name'] = name[0]
dictionaryMemberList[name[0]]['link'] = link[0]
except Exception as e:
print('parsing the html did not work. Possibly you first have to downloadMemberListPagesOfCountries(). The original error message is:', e)
# save interim results to files
f = open('output/' + country +'MemberList.txt', 'w+')
f.write(str(dictionaryMemberList))
f.close
def parseMemberData2dictionary(self, listOfCountries):
for country in listOfCountries:
f = open('output/' + country +'MemberList.txt')
text = f.read()
# replace quotes with double quotes because of JSON specification - RFC7159 which would result in error for json.loads function
text = text.replace("\'", "\"")
dictionaryMemberList = json.loads(text)
for member in dictionaryMemberList:
print('oi')
print(dictionaryMemberList[member]['link'])