<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.gramps-project.org/wiki/index.php?action=history&amp;feed=atom&amp;title=Narrative_Website_Import%2Ftr</id>
	<title>Narrative Website Import/tr - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://www.gramps-project.org/wiki/index.php?action=history&amp;feed=atom&amp;title=Narrative_Website_Import%2Ftr"/>
	<link rel="alternate" type="text/html" href="https://www.gramps-project.org/wiki/index.php?title=Narrative_Website_Import/tr&amp;action=history"/>
	<updated>2026-06-07T22:37:05Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.31.3</generator>
	<entry>
		<id>https://www.gramps-project.org/wiki/index.php?title=Narrative_Website_Import/tr&amp;diff=89939&amp;oldid=prev</id>
		<title>Brtc: Created page with &quot;{{languages/tr|Narrative Website Import}} {{man warn|Outdated code|The Script below was written for the Gramps 2.2 NarrativeWeb and needs to be updated to work with a Gramps 3...&quot;</title>
		<link rel="alternate" type="text/html" href="https://www.gramps-project.org/wiki/index.php?title=Narrative_Website_Import/tr&amp;diff=89939&amp;oldid=prev"/>
		<updated>2022-01-24T21:52:13Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;{{languages/tr|Narrative Website Import}} {{man warn|Outdated code|The Script below was written for the Gramps 2.2 NarrativeWeb and needs to be updated to work with a Gramps 3...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{languages/tr|Narrative Website Import}}&lt;br /&gt;
{{man warn|Outdated code|The Script below was written for the Gramps 2.2 NarrativeWeb and needs to be updated to work with a Gramps 3+ or higher versions.}}&lt;br /&gt;
{{stub}}&lt;br /&gt;
Use a '''Gramps-created [[Gramps_{{man version}}_Wiki_Manual_-_Reports_-_part_7#Narrated_Web_Site|Narrative Website report]]''' to restore your Gramps database.&lt;br /&gt;
&lt;br /&gt;
The program below works by parsing the HTML website (also called &amp;quot;screen scrapping&amp;quot;) and places the data into a [[Gramps_{{man version}}_Wiki_Manual_-_Manage_Family_Trees:_CSV_Import_and_Export#Gramps_Spreadsheet_Import.2FExport|comma-separated value spreadsheet]]. You can then import it directly into Gramps.&lt;br /&gt;
&lt;br /&gt;
To run the program from the command line, provide the URL of the surname list, like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 python getnarrative.py http://somewebsite.com/myfamily/ &amp;gt; import.csv&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Then, in Gramps you should be able to import the file &amp;quot;import.csv&amp;quot; into an empty database.&lt;br /&gt;
&lt;br /&gt;
{{man tip|Code|Use the following code [http://bubo.brynmawr.edu/~dblank/getnarrative.py getnarrative.py] (404 link gone) as a good starting point (As the Script was written for Gramps 2.2 NarrativeWeb and needs to be updated to work with a Gramps 3+ or higher version.&amp;lt;br /&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
# Python script for sucking a GRAMPS Narrative Website back into&lt;br /&gt;
# GRAMPS.&lt;br /&gt;
&lt;br /&gt;
# By Doug Blank &amp;lt;dblank@cs.brynmawr.edu&amp;gt;&lt;br /&gt;
# License: GPL&lt;br /&gt;
# (c) 2007&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
import os, sys, urllib, re&lt;br /&gt;
&lt;br /&gt;
count = 0&lt;br /&gt;
person = {None: None}&lt;br /&gt;
family = {}&lt;br /&gt;
family_pair = {}&lt;br /&gt;
event = {}&lt;br /&gt;
&lt;br /&gt;
def loadPerson(url, surname, firstname):&lt;br /&gt;
    global count, person, family, event, family_pair&lt;br /&gt;
    junk, handle = url.rsplit(&amp;quot;/&amp;quot;,1)&lt;br /&gt;
    handle = handle.replace(&amp;quot;.html&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
    print &amp;gt;&amp;gt; sys.stderr, &amp;quot;   &amp;quot;, count, surname, &amp;quot;, &amp;quot;, firstname&lt;br /&gt;
    count += 1&lt;br /&gt;
    pfp = urllib.urlopen(gurl + &amp;quot;/&amp;quot; + url)&lt;br /&gt;
    contents = pfp.read()&lt;br /&gt;
    state = None&lt;br /&gt;
    pairs = []&lt;br /&gt;
    pdata = {}&lt;br /&gt;
    children = []&lt;br /&gt;
    for line in contents.split(&amp;quot;\n&amp;quot;):&lt;br /&gt;
        matches = re.findall(&amp;quot;&amp;quot;&amp;quot;&amp;lt;td class=&amp;quot;(.*?)&amp;quot;&amp;gt;(.*?)&amp;lt;/td&amp;gt;&amp;quot;&amp;quot;&amp;quot;, line)&lt;br /&gt;
        for match in matches:&lt;br /&gt;
            key, data = match&lt;br /&gt;
            if key in [&amp;quot;box&amp;quot;]:&lt;br /&gt;
                pass # ignore&lt;br /&gt;
            elif key in [&amp;quot;field&amp;quot;, &amp;quot;data&amp;quot;, &amp;quot;category&amp;quot;]:&lt;br /&gt;
                pairs.append((key, data))&lt;br /&gt;
        if state == &amp;quot;Families&amp;quot; and line.startswith(&amp;quot;&amp;lt;a href&amp;quot;): # child?&lt;br /&gt;
            matches = re.match(&amp;quot;&amp;quot;&amp;quot;&amp;lt;a href=&amp;quot;(.*?)&amp;quot;&amp;gt;(.*?)&amp;lt;/a&amp;gt;.*&amp;quot;&amp;quot;&amp;quot;, line)&lt;br /&gt;
            if matches:&lt;br /&gt;
                match = matches.groups()[0]&lt;br /&gt;
                if &amp;quot;/ppl/&amp;quot; in match:&lt;br /&gt;
                    junk, chandle = match.rsplit(&amp;quot;/&amp;quot;, 1)&lt;br /&gt;
                    chandle = chandle.replace(&amp;quot;.html&amp;quot;,&amp;quot;&amp;quot;)&lt;br /&gt;
                    children.append(chandle)&lt;br /&gt;
        elif &amp;quot;&amp;lt;h&amp;quot; in line:&lt;br /&gt;
            matches = re.match(&amp;quot;&amp;lt;h.&amp;gt;(.*?)&amp;lt;/h.&amp;gt;&amp;quot;, line)&lt;br /&gt;
            if matches:&lt;br /&gt;
                if state != None:&lt;br /&gt;
                    if state == &amp;quot;Parents&amp;quot;:&lt;br /&gt;
                        #print &amp;quot;      Parents:&amp;quot;, pairs&lt;br /&gt;
                        father, mother = None, None&lt;br /&gt;
                        for i in range(len(pairs)):&lt;br /&gt;
                            if pairs[i][1] == &amp;quot;Father&amp;quot;:&lt;br /&gt;
                                father = pairs[i+1][1]&lt;br /&gt;
                            if pairs[i][1] == &amp;quot;Mother&amp;quot;:&lt;br /&gt;
                                mother = pairs[i+1][1]&lt;br /&gt;
                        if father:&lt;br /&gt;
                            father = father.replace(&amp;quot;&amp;lt;/a&amp;gt;&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
                            if &amp;quot;/&amp;quot; in father:&lt;br /&gt;
                                junk, fhandle = father.rsplit(&amp;quot;/&amp;quot;, 1)&lt;br /&gt;
                                father, name = fhandle.split(&amp;quot;.html&amp;quot;,1)&lt;br /&gt;
                        if mother:&lt;br /&gt;
                            mother = mother.replace(&amp;quot;&amp;lt;/a&amp;gt;&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
                            if &amp;quot;/&amp;quot; in mother:&lt;br /&gt;
                                junk, mhandle = mother.rsplit(&amp;quot;/&amp;quot;, 1)&lt;br /&gt;
                                mother, name = mhandle.split(&amp;quot;.html&amp;quot;,1)&lt;br /&gt;
                        if (father, mother) in family:&lt;br /&gt;
                            family[(father, mother)].append(handle)&lt;br /&gt;
                        else:&lt;br /&gt;
                            family[(father, mother)] = [handle]&lt;br /&gt;
                    elif state == &amp;quot;Families&amp;quot;:&lt;br /&gt;
                        #print &amp;quot;      Families:&amp;quot;, pairs&lt;br /&gt;
                        mdata = {&amp;quot;me&amp;quot;: handle}&lt;br /&gt;
                        mhandle = None&lt;br /&gt;
                        for (key, value) in pairs:&lt;br /&gt;
                            if key == &amp;quot;category&amp;quot;:&lt;br /&gt;
                                mdata[&amp;quot;type&amp;quot;] = value&lt;br /&gt;
                            elif key == &amp;quot;field&amp;quot;:&lt;br /&gt;
                                mdata[&amp;quot;spouse&amp;quot;] = value&lt;br /&gt;
                            elif key == &amp;quot;data&amp;quot;:&lt;br /&gt;
                                value = value.replace(&amp;quot;&amp;lt;/a&amp;gt;&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
                                if &amp;quot;/&amp;quot; in value:&lt;br /&gt;
                                    junk, handle_name = value.rsplit(&amp;quot;/&amp;quot;, 1)&lt;br /&gt;
                                    mhandle, name = handle_name.split(&amp;quot;.html&amp;quot;,1)&lt;br /&gt;
                        handles = [handle, mhandle]&lt;br /&gt;
                        handles.sort()&lt;br /&gt;
                        #print &amp;quot;adding&amp;quot;, handles, mdata&lt;br /&gt;
                        family_pair[tuple(handles)] = mdata&lt;br /&gt;
                    elif state == &amp;quot;Events&amp;quot;:&lt;br /&gt;
                        #print &amp;quot;      Events:&amp;quot;, pairs&lt;br /&gt;
                        event[(handle, pairs[0][1])] = pairs&lt;br /&gt;
                    elif state.strip() == (firstname + &amp;quot; &amp;quot; + surname).strip():&lt;br /&gt;
                        pdata = {&amp;quot;surname&amp;quot;: surname, &lt;br /&gt;
                                 &amp;quot;firstname&amp;quot;: firstname,&lt;br /&gt;
                                 &amp;quot;children&amp;quot;: children,&lt;br /&gt;
                                 &amp;quot;suffix&amp;quot;: &amp;quot;&amp;quot;}&lt;br /&gt;
                        for i in range(len(pairs)):&lt;br /&gt;
                            if pairs[i][0] == &amp;quot;field&amp;quot;:&lt;br /&gt;
                                pdata[pairs[i][1]] = pairs[i+1][1]&lt;br /&gt;
                            i += 1&lt;br /&gt;
                        person[handle] = pdata&lt;br /&gt;
                    elif state == &amp;quot;Pedigree&amp;quot;:&lt;br /&gt;
                        state = None&lt;br /&gt;
                    elif state in [&amp;quot;Ancestors&amp;quot;, &amp;quot;Narrative&amp;quot;]:&lt;br /&gt;
                        pass&lt;br /&gt;
                    else: # name didn't match exactly&lt;br /&gt;
                        state = state.replace(surname, &amp;quot;&amp;quot;)&lt;br /&gt;
                        state = state.replace(firstname, &amp;quot;&amp;quot;)&lt;br /&gt;
                        suffix = state.strip()&lt;br /&gt;
                        pdata = {&amp;quot;surname&amp;quot;: surname, &lt;br /&gt;
                                 &amp;quot;firstname&amp;quot;: firstname,&lt;br /&gt;
                                 &amp;quot;children&amp;quot;: children,&lt;br /&gt;
                                 &amp;quot;suffix&amp;quot;: &amp;quot;&amp;quot;}&lt;br /&gt;
                        if suffix:&lt;br /&gt;
                            pdata[&amp;quot;suffix&amp;quot;] = suffix&lt;br /&gt;
                        for i in range(len(pairs)):&lt;br /&gt;
                            if pairs[i][0] == &amp;quot;field&amp;quot;:&lt;br /&gt;
                                pdata[pairs[i][1]] = pairs[i+1][1]&lt;br /&gt;
                            i += 1&lt;br /&gt;
                        person[handle] = pdata&lt;br /&gt;
                else:&lt;br /&gt;
                    pass # new person&lt;br /&gt;
                pairs = []&lt;br /&gt;
                state = matches.groups()[0]&lt;br /&gt;
&lt;br /&gt;
def loadSurname(url, surname):&lt;br /&gt;
    sfp = urllib.urlopen(gurl + &amp;quot;/&amp;quot; + url)&lt;br /&gt;
    contents = sfp.read()&lt;br /&gt;
    for line in contents.split(&amp;quot;\n&amp;quot;):&lt;br /&gt;
        list = re.findall(&amp;quot;&amp;quot;&amp;quot;&amp;lt;a href=&amp;quot;(.*?)&amp;quot;&amp;gt;(.*?)&amp;lt;/a&amp;gt;&amp;quot;&amp;quot;&amp;quot;, line)&lt;br /&gt;
        for surnameURL in list:&lt;br /&gt;
            url, firstname = surnameURL&lt;br /&gt;
            if url.endswith(&amp;quot;.html&amp;quot;) and &amp;quot;/ppl/&amp;quot; in url:&lt;br /&gt;
                prefix, purl = url.split(&amp;quot;/ppl/&amp;quot;)&lt;br /&gt;
                loadPerson(&amp;quot;/ppl/&amp;quot; + purl, surname, firstname)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
gurl = sys.argv[1] # URL of surnames&lt;br /&gt;
fp = urllib.urlopen(gurl) &lt;br /&gt;
contents = fp.read() # read in website&lt;br /&gt;
for line in contents.split(&amp;quot;\n&amp;quot;):&lt;br /&gt;
    list = re.findall(&amp;quot;&amp;quot;&amp;quot;&amp;lt;a href=&amp;quot;(.*?)&amp;quot;&amp;gt;(.*?)&amp;lt;/a&amp;gt;&amp;quot;&amp;quot;&amp;quot;, line)&lt;br /&gt;
    for surnameURL in list:&lt;br /&gt;
        url, surname = surnameURL&lt;br /&gt;
        if url.endswith(&amp;quot;.html&amp;quot;) and url.startswith(&amp;quot;srn&amp;quot;):&lt;br /&gt;
            print &amp;gt;&amp;gt; sys.stderr, &amp;quot;Processing surname&amp;quot;, surname, &amp;quot;...&amp;quot;&lt;br /&gt;
            loadSurname(*surnameURL)&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;person,firstname,lastname,suffix,gender&amp;quot;&lt;br /&gt;
for h in person:&lt;br /&gt;
    if h:&lt;br /&gt;
        print '&amp;quot;%s&amp;quot;,&amp;quot;%s&amp;quot;,&amp;quot;%s&amp;quot;,&amp;quot;%s&amp;quot;,&amp;quot;%s&amp;quot;' % (h, person[h][&amp;quot;firstname&amp;quot;], &lt;br /&gt;
                                            person[h][&amp;quot;surname&amp;quot;], &lt;br /&gt;
                                            person[h][&amp;quot;suffix&amp;quot;], &lt;br /&gt;
                                            person[h][&amp;quot;Gender&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
for fam in family_pair:&lt;br /&gt;
    data = family_pair[fam]&lt;br /&gt;
    h1, h2 = fam&lt;br /&gt;
    p1, p2 = None, None&lt;br /&gt;
    if h1 in person:&lt;br /&gt;
        p1 = person[h1]&lt;br /&gt;
    if h2 in person:&lt;br /&gt;
        p2 = person[h2]&lt;br /&gt;
    if p1 and p2:&lt;br /&gt;
        if p1[&amp;quot;Gender&amp;quot;] == &amp;quot;male&amp;quot; and p2[&amp;quot;Gender&amp;quot;] == &amp;quot;female&amp;quot;:&lt;br /&gt;
            if (h1, h2) in family:&lt;br /&gt;
                family[(h1,h2)].append(data[&amp;quot;me&amp;quot;])&lt;br /&gt;
            else:&lt;br /&gt;
                family[(h1,h2)] = [data[&amp;quot;me&amp;quot;]]&lt;br /&gt;
        else:&lt;br /&gt;
            if (h2, h1) in family:&lt;br /&gt;
                family[(h2,h1)].append(data[&amp;quot;me&amp;quot;])&lt;br /&gt;
            else:&lt;br /&gt;
                family[(h2,h1)] = [data[&amp;quot;me&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
print&lt;br /&gt;
print &amp;quot;marriage,parent1,parent2&amp;quot;&lt;br /&gt;
count = 1&lt;br /&gt;
marriage = {}&lt;br /&gt;
for pair in family:&lt;br /&gt;
    marriage[pair] = &amp;quot;F%04d&amp;quot; % count&lt;br /&gt;
    print '&amp;quot;%s&amp;quot;,&amp;quot;%s&amp;quot;,&amp;quot;%s&amp;quot;' % (marriage[pair], pair[0], pair[1])&lt;br /&gt;
    count += 1&lt;br /&gt;
&lt;br /&gt;
print&lt;br /&gt;
print &amp;quot;family,child&amp;quot;&lt;br /&gt;
for pair in family:&lt;br /&gt;
    kids = family[pair]&lt;br /&gt;
    kids = set(kids)&lt;br /&gt;
    for kid in kids:&lt;br /&gt;
        if (kid != pair[0]) or (kid != pair[1]):&lt;br /&gt;
            print '&amp;quot;%s&amp;quot;,&amp;quot;%s&amp;quot;' % (marriage[pair], kid)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
Read the following discussion about this code at [https://sourceforge.net/p/gramps/mailman/gramps-users/thread/20071126154619.GA41656%40eris.discordians.net/#msg11668864 Lost grdb(2007)] &amp;amp; [https://sourceforge.net/p/gramps/mailman/message/28021878/]&lt;br /&gt;
&lt;br /&gt;
[[Category:Tr:Documentation]]&lt;br /&gt;
[[Category:Developers/General]]&lt;/div&gt;</summary>
		<author><name>Brtc</name></author>
		
	</entry>
</feed>