- Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathleetcode_problems.py
More file actions
Latest commit
executable file
·123 lines (109 loc) · 4.05 KB
/
Copy pathleetcode_problems.py
File metadata and controls
executable file
·123 lines (109 loc) · 4.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/usr/bin/env python
# -*- coding=utf-8 -*-
importsys
importre
importos
importargparse
importrequests
fromlxmlimporthtmlaslxml_html
try:
importhtml
exceptImportError:
importHTMLParser
html=HTMLParser.HTMLParser()
try:
importcPickleaspk
exceptImportError:
importpickleaspk
classLeetcodeProblems(object):
defget_problems_info(self):
leetcode_url='https://leetcode.com/problemset/algorithms'
res=requests.get(leetcode_url)
ifnotres.ok:
print('request error')
sys.exit()
cm=res.text
cmt=cm.split('tbody>')[-2]
indexs=re.findall(r'<td>(\d+)</td>', cmt)
problem_urls= ['https://leetcode.com'+url \
forurlinre.findall(
r'<a href="(/problems/.+?)"', cmt)]
levels=re.findall(r"<td value='\d*'>(.+?)</td>", cmt)
tinfos=zip(indexs, levels, problem_urls)
assert (len(indexs) ==len(problem_urls) ==len(levels))
infos= []
forinfointinfos:
res=requests.get(info[-1])
ifnotres.ok:
print('request error')
sys.exit()
tree=lxml_html.fromstring(res.text)
title=tree.xpath('//meta[@property="og:title"]/@content')[0]
description=tree.xpath('//meta[@property="description"]/@content')
ifnotdescription:
description=tree.xpath('//meta[@property="og:description"]/@content')[0]
else:
description=description[0]
description=html.unescape(description.strip())
tags=tree.xpath('//div[@id="tags"]/following::a[@class="btn btn-xs btn-primary"]/text()')
infos.append(
{
'title': title,
'level': info[1],
'index': int(info[0]),
'description': description,
'tags': tags
}
)
withopen('leecode_problems.pk', 'wb') asg:
pk.dump(infos, g)
returninfos
defto_text(self, pm_infos):
ifself.args.index:
key='index'
elifself.args.title:
key='title'
elifself.args.tag:
key='tags'
elifself.args.level:
key='level'
else:
key='index'
infos=sorted(pm_infos, key=lambdai: i[key])
text_template='## {index} - {title}\n' \
'~{level}~ {tags}\n' \
'{description}\n'+'\n'*self.args.line
text=''
forinfoininfos:
ifself.args.rm_blank:
info['description'] =re.sub(r'[\n\r]+', r'\n', info['description'])
text+=text_template.format(**info)
withopen('leecode problems.txt', 'w') asg:
g.write(text)
defrun(self):
ifos.path.exists('leecode_problems.pk') andnotself.args.redownload:
withopen('leecode_problems.pk', 'rb') asf:
pm_infos=pk.load(f)
else:
pm_infos=self.get_problems_info()
print('find %s problems.'%len(pm_infos))
self.to_text(pm_infos)
defhandle_args(argv):
p=argparse.ArgumentParser(description='extract all leecode problems to location')
p.add_argument('--index', action='store_true', help='sort by index')
p.add_argument('--level', action='store_true', help='sort by level')
p.add_argument('--tag', action='store_true', help='sort by tag')
p.add_argument('--title', action='store_true', help='sort by title')
p.add_argument('--rm_blank', action='store_true', help='remove blank')
p.add_argument('--line', action='store', type=int, default=10, help='blank of two problems')
p.add_argument('-r', '--redownload', action='store_true', help='redownload data')
args=p.parse_args(argv[1:])
returnargs
defmain(argv):
args=handle_args(argv)
x=LeetcodeProblems()
x.args=args
x.run()
if__name__=='__main__':
argv=sys.argv
main(argv)