9 def __init__(self, name):
11 self.reward_kind = None
14 def __init__(self, name):
21 def is_upgrade_for(self, other):
22 aps = self.amount/self.duration
23 other_aps = other.amount/other.duration
24 return (aps>other_aps and self.amount>other.amount)
27 def __init__(self, name):
29 self.primary_attribute = None
30 self.secondary_attribute = None
33 self.drop_only = False
35 class WikiParser(html.parser.HTMLParser):
37 super(WikiParser, self).__init__()
41 def handle_starttag(self, tag, attrs):
47 if n=="class" and "c-item-hoverbox__display" in v:
50 def handle_endtag(self, tag):
55 class WikiTableParser(WikiParser):
57 super(WikiTableParser, self).__init__()
59 self.in_items_table = False
63 self.current_item = None
65 def handle_starttag(self, tag, attrs):
66 super(WikiTableParser, self).handle_starttag(tag, attrs)
70 if n=="class" and "wikitable" in v:
71 self.in_items_table = True
74 self.current_item = None
77 if self.in_items_table:
80 def handle_endtag(self, tag):
81 super(WikiTableParser, self).handle_endtag(tag)
84 self.in_items_table = False
88 def handle_data(self, data):
98 self.current_item = self.create_item(data)
100 self.items.append(self.current_item)
101 elif self.current_item:
102 self.handle_value(self.column, data)
104 def create_item(self, name):
107 def handle_value(self, column, data):
110 class DivinationCardsParser(WikiTableParser):
111 reward_kinds = ("currency", "map", "unique", "links", "skillgem", "rare", "magic", "other")
113 def handle_starttag(self, tag, attrs):
114 super(DivinationCardsParser, self).handle_starttag(tag, attrs)
116 if tag=="span" and not self.ignore:
117 if self.in_cell and self.current_item and not self.current_item.reward_kind and self.column==3:
121 self.current_item.reward_kind = "currency"
123 self.current_item.reward_kind = "unique"
125 self.current_item.reward_kind = "rare"
126 elif "-magic" in v or "-mod" in v:
127 self.current_item.reward_kind = "magic"
129 self.current_item.reward_kind = "skillgem"
131 def handle_endtag(self, tag):
132 super(DivinationCardsParser, self).handle_endtag(tag)
135 if self.current_item and not self.current_item.reward_kind:
136 self.current_item.reward_kind = "other"
138 def create_item(self, name):
141 def handle_value(self, column, data):
144 self.current_item.reward_kind = "links"
146 self.current_item.reward_kind = "map"
148 class FlasksParser(WikiTableParser):
149 def __init__(self, utility=False):
150 super(FlasksParser, self).__init__()
152 self.utility = utility
154 def handle_endtag(self, tag):
155 super(FlasksParser, self).handle_endtag(tag)
158 if self.current_item:
159 for it in self.items:
160 if not it.upgrade and self.current_item.is_upgrade_for(it):
161 it.upgrade = self.current_item
163 def create_item(self, name):
164 if name.endswith("Flask"):
167 def handle_value(self, column, data):
169 self.current_item.droplevel = int(data)
170 elif column==3 and not self.utility:
171 self.current_item.amount = int(data)
172 elif (column==4 and not self.utility) or (column==3 and self.utility):
173 self.current_item.duration = float(data)
175 class SkillGemListParser(WikiParser):
177 super(SkillGemListParser, self).__init__()
179 self.in_subheading = False
183 def handle_starttag(self, tag, attrs):
184 super(SkillGemListParser, self).handle_starttag(tag, attrs)
187 self.in_subheading = True
189 if self.in_list and not self.ignore:
194 def handle_endtag(self, tag):
195 super(SkillGemListParser, self).handle_endtag(tag)
198 self.in_subheading = False
200 def handle_data(self, data):
203 if self.in_subheading:
204 self.in_list = (data=="List")
206 class SkillGemParser(WikiParser):
207 prices = (("alchemy", "Orb of Alchemy"),
208 ("chance", "Orb of Chance"),
209 ("alteration", "Orb of Alteration"),
210 ("transmute", "Orb of Transmutation"),
211 ("wisdom", "Scroll of Wisdom"))
214 super(SkillGemParser, self).__init__()
217 self.in_heading = False
218 self.in_subheading = False
219 self.in_subheading = False
221 self.in_box_heading = False
222 self.in_purchase = False
223 self.in_progression = False
224 self.in_acquisition = False
225 self.have_acquisition_data = False
228 self.attribute_reqs = []
230 def handle_starttag(self, tag, attrs):
231 super(SkillGemParser, self).handle_starttag(tag, attrs)
234 self.in_heading = True
236 self.in_subheading = True
242 if n=="class" and "item-box" in v:
247 if n=="class" and "header" in v:
248 self.in_purchase = False
249 self.in_box_heading = True
255 elif tag=="td" or tag=="th":
258 if self.in_progression and self.column>=3:
261 self.attribute_reqs.append([v, 0])
264 if n=="id" and v=="footer":
265 if not self.have_acquisition_data:
266 self.item.drop_only = True
268 def handle_endtag(self, tag):
269 super(SkillGemParser, self).handle_endtag(tag)
272 self.in_heading = False
274 self.in_subheading = False
279 self.in_box_heading = False
281 if self.in_progression and self.row==2 and self.attribute_reqs:
282 self.attribute_reqs.sort(key=lambda r: r[1])
283 self.item.primary_attribute = self.attribute_reqs[0][0]
284 if len(self.attribute_reqs)>1:
285 self.item.secondary_attribute = self.attribute_reqs[1][0]
287 def handle_data(self, data):
294 paren = name.find('(')
296 name = name[:paren].strip()
297 self.item = SkillGem(name)
298 if name.startswith("Vaal"):
299 self.item.vaal = True
300 elif self.in_subheading:
301 self.in_progression = ("progression" in data)
302 self.in_acquisition = ("acquisition" in data)
303 elif self.in_box_heading:
304 if "Purchase" in data:
305 self.in_purchase = True
306 elif self.in_purchase:
308 for p, n in SkillGemParser.prices:
311 elif self.in_progression:
312 if self.row==2 and self.column>=3 and self.column<3+len(self.attribute_reqs):
313 self.attribute_reqs[self.column-3][1] = int(data)
314 elif self.in_acquisition:
315 self.have_acquisition_data = True
317 def scrape_flasks(out, url, kind):
318 r = requests.get(url)
320 p.feed(codecs.decode(r.content, r.encoding))
322 out.write('category "flask.{}.best_at_level"\n'.format(kind))
323 out.write('{\n\tclass "Flask";\n\tor\n\t{\n')
325 out.write("\t\tand\n\t\t{\n")
326 out.write('\t\t\tbase_type "{}";\n'.format(it.name))
328 out.write("\t\t\titem_level {} {};\n".format(it.droplevel, it.upgrade.droplevel-1))
330 out.write("\t\t\tmin_item_level {};\n".format(it.droplevel))
331 out.write("\t\t};\n")
332 out.write("\t};\n};\n")
335 r = requests.get("https://pathofexile.gamepedia.com/List_of_divination_cards")
336 p = DivinationCardsParser()
337 p.feed(codecs.decode(r.content, r.encoding))
342 by_reward.setdefault(it.reward_kind, []).append(it)
344 out = open("cards.txt", "w")
345 for r in DivinationCardsParser.reward_kinds:
346 out.write('category "card.{}"\n'.format(r))
347 out.write('{\n\tclass "Card";\n\tor\n\t{\n')
348 for it in by_reward[r]:
349 out.write('\t\tbase_type "{}";\n'.format(it.name))
350 out.write("\t};\n};\n")
352 out = open("flasks.txt", "w")
353 scrape_flasks(out, "https://pathofexile.gamepedia.com/Life_Flasks", "life")
354 scrape_flasks(out, "https://pathofexile.gamepedia.com/Mana_Flasks", "mana")
355 scrape_flasks(out, "https://pathofexile.gamepedia.com/Hybrid_Flasks", "hybrid")
357 p = FlasksParser(True)
358 r = requests.get("https://pathofexile.gamepedia.com/Utility_Flasks")
359 p.feed(codecs.decode(r.content, r.encoding))
360 r = requests.get("https://pathofexile.gamepedia.com/Critical_Utility_Flasks")
361 p.feed(codecs.decode(r.content, r.encoding))
363 out.write('category "flask.utility"\n{\n\tclass "Flask";\n\tor\n\t{\n')
365 out.write('\t\tbase_type "{}";\n'.format(it.name))
366 out.write("\t};\n};\n")
368 r = requests.get("https://pathofexile.gamepedia.com/List_of_skill_gems")
369 p = SkillGemListParser()
370 p.feed(codecs.decode(r.content, r.encoding))
376 r2 = requests.get("https://pathofexile.gamepedia.com"+l)
377 p2 = SkillGemParser()
378 p2.feed(codecs.decode(r2.content, r2.encoding))
381 sys.stdout.write(prefix+"{}\n".format(p2.item.name))
382 prefix = "\033[1A\033[K"
384 sys.stdout.write(prefix)
386 out = open("skillgems.txt", "w")
387 out.write('category "skillgem.special.vaal"\n{\n\tclass "Skill Gem";\n\tor\n\t{\n')
390 out.write('\t\tbase_type "{}";\n'.format(g.name))
391 out.write("\t};\n};\n")
393 out.write('category "skillgem.special.drop"\n{\n\tclass "Skill Gem";\n\tor\n\t{\n')
395 if (g.drop_only or not g.price) and not g.vaal:
396 out.write('\t\tbase_type "{}";\n'.format(g.name))
397 out.write("\t};\n};\n")
399 for p, n in SkillGemParser.prices:
400 out.write('category "skillgem.price.{}"\n'.format(p))
401 out.write('{\n\tclass "Skill Gem";\n\tor\n\t{\n')
403 if not g.drop_only and g.price==p:
404 out.write('\t\tbase_type "{}";\n'.format(g.name))
405 out.write("\t};\n};\n")
407 for a in ["strength", "dexterity", "intelligence"]:
408 out.write('category "skillgem.attribute.{}"\n'.format(a))
409 out.write('{\n\tclass "Skill Gem";\n\tor\n\t{\n')
411 if g.primary_attribute==a:
412 out.write('\t\tbase_type "{}";\n'.format(g.name))
413 out.write("\t};\n};\n")
415 if __name__=="__main__":