-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathgiveaways.py
102 lines (80 loc) · 3.21 KB
/
giveaways.py
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
import requests
import sys
from getpass import getpass
from lxml import html
def login(session, username, password):
page = session.get('https://www.goodreads.com/')
tree = html.fromstring(page.content)
form = tree.xpath('//div[@id="signInForm"]')[0]
authenticity_token = form.xpath('.//input[@name="authenticity_token"]/@value')[0]
n = form.xpath('.//input[@name="n"]/@value')[0]
payload = {
'user[email]': username,
'user[password]': password,
'remember_me': 'on',
'authenticity_token': authenticity_token,
'n': n
}
response = session.post('https://www.goodreads.com/user/sign_in?source=home', data=payload)
print('[*] Successfully logged in to Goodreads!')
def scrape_giveaways(session):
giveaways = []
count = 1
while True:
page = session.get('https://www.goodreads.com/giveaway?sort=ending_soon', params={'page': count})
tree = html.fromstring(page.content)
lis = tree.xpath('//li[@class="listElement giveawayListItem"]')
if not lis: break
for li in lis:
ID = int(li.xpath('.//a[@class="actionLink detailsLink"]/@href')[0].rsplit('/', 1)[-1].split('-')[0])
entered = not bool(li.xpath('.//a[@class="gr-button"]/@href'))
giveaway = {
'Name': li.xpath('.//a[@class="bookTitle"]/text()')[0],
'URL': li.xpath('.//a[@class="bookTitle"]/@href')[0],
'Entered': entered,
'ID': ID
}
giveaways.append(giveaway)
count = count + 1
print('[*] {} giveaways scraped.'.format(len(giveaways)))
giveaways = [g for g in giveaways if not g['Entered']]
print('[*] {} giveaways to enter!'.format(len(giveaways)))
return giveaways
def enter_giveaway(session, identifier, name=None):
page = session.get('https://www.goodreads.com/giveaway/enter_choose_address/{}'.format(identifier))
tree = html.fromstring(page.content)
try:
address = int(tree.xpath('//a[@class="gr-button gr-button--small"]/@id')[0][13:])
except IndexError:
print('''
[!] Looks like you didn\'t read the README properly. That\'s a shame.
Here\'s an important and relevant part of the README restated.
Before running the script, make sure you've entered a giveaway manually at least once. The first time involves setting up a new address, and the script assumes that it's done.
''')
sys.exit()
page = session.get('https://www.goodreads.com/giveaway/enter_print_giveaway/{}'.format(identifier), params={'address': address})
tree = html.fromstring(page.content)
authenticity_token = tree.xpath('//input[@name="authenticity_token"]/@value')[0]
payload = {
'authenticity_token': authenticity_token,
'entry_terms': 1,
'commit': 'Enter Giveaway'
}
response = session.post('https://www.goodreads.com/giveaway/enter_print_giveaway/{}'.format(identifier),
params={'address': address}, data=payload)
print('[*] Entered giveaway for: {0} - {1}'.format(identifier, name))
def main():
session = requests.Session()
username = input('[?] Enter your Goodreads username: ')
password = getpass('[?] Enter your Goodreads password: ')
login(session, username, password)
giveaways = scrape_giveaways(session)
print()
for giveaway in giveaways:
if not giveaway['Entered']:
try:
enter_giveaway(session, giveaway['ID'], name=giveaway['Name'])
except:
print('Couldn\'t do it. :(')
if __name__=='__main__':
main()