Skip to content

Commit 953e301

Browse files
committed
Added crawler for osu
1 parent cba38b9 commit 953e301

4 files changed

Lines changed: 91 additions & 0 deletions

File tree

WebCrawlers/osu.ppy.sh/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
This crawler is for crawling the music packs from osu,
2+
and they will be used for preparing a mobile game project!

WebCrawlers/osu.ppy.sh/getlists.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# this file is used for getting pack lists and store them in the database
2+
import re
3+
import socket
4+
import urllib.request as urllib2
5+
6+
# the list can be get from: https://osu.ppy.sh/p/packlist?t=s
7+
import settings
8+
from property_db import PropertyDb
9+
10+
FULL_LIST = 'https://osu.ppy.sh/p/packlist?t=s'
11+
LIST_PATTERN = r'"expandPack\(\'(.+?)\'\)"'
12+
MAP_URL_PATTERN = 'https://osu.ppy.sh/pages/include/packlist-info.php?n={}'
13+
PAGE_PATTERN = r'<h2>(.+?)</h2>.+?<div>.+?href="(.+?)">' # group 1 - file name; group 2 - link
14+
socket.setdefaulttimeout(15)
15+
16+
"""
17+
download a page by passed url
18+
"""
19+
def download(url):
20+
while True:
21+
try:
22+
opener = urllib2.build_opener()
23+
opener.addheaders.append(('Cookie', settings.COOKIES))
24+
opener.addheaders.append(('User-Agent', settings.USER_AGENT))
25+
f = opener.open(url)
26+
b = f.read()
27+
except Exception as e:
28+
print(e)
29+
print('-- trying again: {}'.format(url))
30+
continue
31+
return b
32+
33+
34+
"""
35+
the main function
36+
"""
37+
list_page = download(FULL_LIST)
38+
propertyDb = PropertyDb()
39+
for match in re.finditer(LIST_PATTERN, list_page, re.DOTALL | re.MULTILINE):
40+
key = match.group(1)
41+
print('working on pack: {}'.format(key))
42+
43+
# if this pack is not downloaded
44+
if propertyDb.does_record_exist(key):
45+
continue
46+
47+
current_page = download(MAP_URL_PATTERN.format(key))
48+
page_matcher = re.search(PAGE_PATTERN, current_page, re.DOTALL | re.MULTILINE)
49+
50+
if page_matcher:
51+
propertyDb.save_or_overwrite_data(key, current_page)
52+
else:
53+
# if not found
54+
print('-- ERROR not found things on page on key {}: {}'.format(key, current_page))
55+
56+
print('done')
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# the file for handling the property db
2+
import sqlite3
3+
4+
import settings
5+
6+
"""
7+
the property-like db
8+
"""
9+
class PropertyDb:
10+
11+
def __init__(self):
12+
self.conn = sqlite3.connect(settings.DB_NAME)
13+
self.init_db()
14+
15+
16+
def init_db(self):
17+
self.conn.execute('CREATE TABLE IF NOT EXISTS properties (name TEXT PRIMARY KEY, value TEXT, time DATETIME DEFAULT current_timestamp);')
18+
19+
20+
def does_record_exist(self, key):
21+
return self.get_value(key) is not None
22+
23+
def save_or_overwrite_data(self, key, value):
24+
self.conn.execute("INSERT OR REPLACE INTO properties(name, value, time) VALUES (?, ?, current_timestamp);", (key, value,))
25+
26+
27+
def get_value(self, key):
28+
self.conn.execute("SELECT * FROM properties WHERE name = ?;", (key,))
29+
return self.conn.fetchone()

WebCrawlers/osu.ppy.sh/settings.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# NOTE: DO NOT COMMIT THIS FILE AFTER FILLING SECRET INFORMATION
2+
DB_NAME = 'url.db'
3+
COOKIES = '' # TODO: fill this
4+
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'

0 commit comments

Comments
 (0)