update lecture material to move to notebook
[harrypotter-wikipedia-cdsw] / build_hpwp_dataset.py
1 #!/usr/bin/env python
2 # coding=utf-8
3
4 import encoding_fix
5 import requests
6
7 # get_article_revisions is a function that takes an article title in
8 # wikipedia and return a list of all the revisions and metadata for
9 # that article
10 def get_article_revisions(title):
11     revisions = []
12
13     # create a base url for the api and then a normal url which is initially
14     # just a copy of it
15     # The following line is what the requests call is doing, basically.
16     # "http://en.wikipedia.org/w/api.php/?action=query&titles={0}&prop=revisions&rvprop=flags|timestamp|user|size|ids&rvlimit=500&format=json&continue=".format(title)
17     wp_api_url = "http://en.wikipedia.org/w/api.php/"
18
19     parameters = {'action' : 'query',
20                   'titles' : title,
21                   'prop' : 'revisions',
22                   'rvprop' : 'flags|timestamp|user|size|ids',
23                   'rvlimit' : 500,
24                   'format' : 'json',
25                   'continue' : '' }
26
27     # we'll repeat this forever (i.e., we'll only stop when we find
28     # the "break" command)
29     while True:
30         # the first line open the urls but also handles unicode urls
31         call = requests.get(wp_api_url, params=parameters)
32         api_answer = call.json()
33
34         # get the list of pages from the json object
35         pages = api_answer["query"]["pages"]
36
37         # for every page, (there should always be only one) get its revisions:
38         for page in pages.keys():
39             query_revisions = pages[page]["revisions"]
40
41             # for every revision, first we do some cleaning up
42             for rev in query_revisions:
43                 #print(rev)
44                 # let's continue/skip this revision if the user is hidden
45                 if "userhidden" in rev:
46                     continue
47                 
48                 # 1: add a title field for the article because we're going to mix them together
49                 rev["title"] = title
50
51                 # 2: let's "recode" anon so it's true or false instead of present/missing
52                 if "anon" in rev:
53                     rev["anon"] = True
54                 else:
55                     rev["anon"] = False
56
57                 # 3: let's recode "minor" in the same way
58                 if "minor" in rev:
59                     rev["minor"] = True
60                 else:
61                     rev["minor"] = False
62
63                 # we're going to change the timestamp to make it work a little better in excel/spreadsheets
64                 rev["timestamp"] = rev["timestamp"].replace("T", " ")
65                 rev["timestamp"] = rev["timestamp"].replace("Z", "")
66
67                 # finally, save the revisions we've seen to a varaible
68                 revisions.append(rev)
69
70         # 'continue' tells us there's more revisions to add
71         if 'continue' in api_answer:
72             # replace the 'continue' parameter with the contents of the
73             # api_answer dictionary.
74             parameters.update(api_answer['continue'])
75         else:
76             break
77
78     # return all the revisions for this page
79     return(revisions)
80
81 category = "Harry Potter"
82
83 # we'll use another api called catscan2 to grab a list of pages in
84 # categories and subcategories. it works like all the other apis we've
85 # studied!
86 #
87 # The following requests call basically does the same thing as this string:
88 # "http://tools.wmflabs.org/catscan2/catscan2.php?depth=10&categories={0}&doit=1&format=json".format(category)
89 url_catscan = "https://petscan.wmflabs.org/"
90
91 parameters = {'depth' : 10,
92               'categories' : category,
93               'format' : 'json',
94               'doit' : 1}
95
96 # r = requests.get("http://tools.wmflabs.org/catscan2/catscan2.php?depth=10&categories=Harry Potter&doit=1&format=json"
97
98 r = requests.get(url_catscan, params=parameters)
99 articles_json = r.json()
100 articles = articles_json["*"][0]["a"]["*"]
101
102 # open a file to write all the output
103 output = open("hp_wiki.tsv", "w", encoding="utf-8")
104 output.write("\t".join(["title", "user", "timestamp", "size", "anon", "minor", "revid"]) + "\n")
105
106 # for every article
107 for article in articles:
108     # skip this until it's an article
109     if article["namespace"] != 0:
110         continue
111
112     # first grab the article's title
113     title = article["title"]
114     print(title)
115
116     # get the list of revisions from our function and then iterate through it,
117     # printing it to our output file
118     revisions = get_article_revisions(title)
119     for rev in revisions:
120         output.write("\t".join(['"' + rev["title"] + '"', '"' + rev["user"] + '"',
121                                rev["timestamp"], str(rev["size"]), str(rev["anon"]),
122                                str(rev["minor"]), str(rev["revid"])]) + "\n")
123
124 # close the file, we're done here!
125 output.close()
126

Benjamin Mako Hill || Want to submit a patch?