• Log InLog In
  • Register
Liquid`
Team Liquid Liquipedia
EDT 08:26
CET 13:26
KST 21:26
  • Home
  • Forum
  • Calendar
  • Streams
  • Liquipedia
  • Features
  • Store
  • EPT
  • TL+
  • StarCraft 2
  • Brood War
  • Smash
  • Heroes
  • Counter-Strike
  • Overwatch
  • Liquibet
  • Fantasy StarCraft
  • TLPD
  • StarCraft 2
  • Brood War
  • Blogs
Forum Sidebar
Events/Features
News
Featured News
[ASL20] Finals Preview: Arrival10TL.net Map Contest #21: Voting10[ASL20] Ro4 Preview: Descent11Team TLMC #5: Winners Announced!3[ASL20] Ro8 Preview Pt2: Holding On9
Community News
BSL21 Open Qualifiers Week & CONFIRM PARTICIPATION1Crank Gathers Season 2: SC II Pro Teams4Merivale 8 Open - LAN - Stellar Fest3Chinese SC2 server to reopen; live all-star event in Hangzhou22Weekly Cups (Oct 13-19): Clem Goes for Four3
StarCraft 2
General
Could we add "Avoid Matchup" Feature for rankgame Smart servos says it affects liberators as well RotterdaM "Serral is the GOAT, and it's not close" Chinese SC2 server to reopen; live all-star event in Hangzhou The New Patch Killed Mech!
Tourneys
Crank Gathers Season 2: SC II Pro Teams Merivale 8 Open - LAN - Stellar Fest $5,000+ WardiTV 2025 Championship $3,500 WardiTV Korean Royale S4 Tenacious Turtle Tussle
Strategy
Custom Maps
Map Editor closed ?
External Content
Mutation # 497 Battle Haredened Mutation # 496 Endless Infection Mutation # 495 Rest In Peace Mutation # 494 Unstable Environment
Brood War
General
BSL Season 21 BSL Team A vs Koreans - Sat-Sun 16:00 CET ASL20 Pre-season Tier List ranking! ASL Runner-Up Race Stats [ASL20] Finals Preview: Arrival
Tourneys
[ASL20] Grand Finals BSL21 Open Qualifiers Week & CONFIRM PARTICIPATION ASL final tickets help [ASL20] Semifinal A
Strategy
Current Meta Soma's 9 hatch build from ASL Game 2 Simple Questions, Simple Answers Roaring Currents ASL final
Other Games
General Games
Path of Exile Stormgate/Frost Giant Megathread General RTS Discussion Thread Nintendo Switch Thread Dawn of War IV
Dota 2
Official 'what is Dota anymore' discussion LiquidDota to reintegrate into TL.net
League of Legends
Heroes of the Storm
Simple Questions, Simple Answers Heroes of the Storm 2.0
Hearthstone
Deck construction bug Heroes of StarCraft mini-set
TL Mafia
TL Mafia Community Thread SPIRED by.ASL Mafia {211640}
Community
General
Things Aren’t Peaceful in Palestine US Politics Mega-thread Russo-Ukrainian War Thread YouTube Thread The Chess Thread
Fan Clubs
White-Ra Fan Club The herO Fan Club!
Media & Entertainment
Anime Discussion Thread [Manga] One Piece Korean Music Discussion Series you have seen recently... Movie Discussion!
Sports
Formula 1 Discussion 2024 - 2026 Football Thread MLB/Baseball 2023 TeamLiquid Health and Fitness Initiative For 2023 NBA General Discussion
World Cup 2022
Tech Support
SC2 Client Relocalization [Change SC2 Language] Linksys AE2500 USB WIFI keeps disconnecting Computer Build, Upgrade & Buying Resource Thread
TL Community
The Automated Ban List Recent Gifted Posts
Blogs
The Benefits Of Limited Comm…
TrAiDoS
Sabrina was soooo lame on S…
Peanutsc
Our Last Hope in th…
KrillinFromwales
Certified Crazy
Hildegard
Customize Sidebar...

Website Feedback

Closed Threads



Active: 1582 users

autofan: A tool for updating fan clubs

Blogs > Loser777
Post a Reply
Loser777
Profile Blog Joined January 2008
1931 Posts
Last Edited: 2013-09-06 01:38:33
September 06 2013 01:08 GMT
#1
The member lists of most fan clubs, are, at the moment, unmanageable. Some of the larger ones haven't had their lists updated in over two years.

I'm currently working on a web scraper which would allow these lists to be updated automatically, without any manual labor.
https://github.com/eqy/autofan

The current development environment is Arch GNU/Linux, and I've ported it over to Ubuntu 12.04 with almost no issues (after fixing some compatibility issues with Ubuntu's slightly staler libraries). If you'd like to build it, simply clone the repository and make sure you have the libraries specified in the README. If you encounter any problems trying to build, let me know.

It is trivial to build: [animated-gif]
http://i.imgur.com/I4EmOgX.gif

And trivial to use: [animated-gif]
http://i.imgur.com/H05aOgQ.gif


It's still in the very early stages of development, so there are still a number of obvious issues:
  • The rules for adding people to fan clubs are still very simple at the moment, and there are only a few of them.
  • People can be added multiple times. This most obvious cause of this is through quotes (see below). This is trivially fixable through any number of tools (e.g. sort -u, regex, etc.).
  • Quotes are not handled well--the parser can't distinguish what someone actually said and what the person they're quoting said. This is a slightly annoying issue, because despite the copious amounts of tables that TL uses, quotes are not explicitly tables--so the parser that I'm using doesn't identify quotes as separate elements. The most obvious solution I see at the moment is to do some kind of regex matching where posts that say "...wrote:" are checked against previous posts. Finding posts that likely contain quotes is trivial, but the matching step would be computationally expensive.
  • It still spits out mountains of debug information to stderr (actual output goes to stdout) because I still need the debug information to add features/fix the issues above.


The plan is to either eventually port it over to Windows after slapping on some sort of qt-based interface so it becomes usable for the 99% of TL or to launch it as some sort of web app. Both are equally foreign territory for me.
If you feel like contributing, feel free to send me a pull request! When development quiets down, I also plan on repackaging the core of this project (a library called tltopic) so that it can be used for other projects that want to parse TL threads.

History of the project:
(I don't have db access scraping is all I can do #YOLO)

I began thinking about this around two weeks ago and have been lazily hacking at it since. After my REU program ended this summer, I realized that I had pretty much been writing exclusively MATLAB for the last year or so. That year or so destroyed whatever tiny amount of coding chops in C/C++ I had (my background is not in CS), and my little weekend side projects in Python/Arduino were not helping. The implementation language of C++ reflects my need to refresh my knowledge--seriously, who writes web scrapers in C++ these days? I think this justifies the language choice as mental masturbation, not masochism.

I basically had zero knowledge of any of the non-standard libraries I used in this project (libcurl, libtidy, libxml2, boost) before I started. Everything was inspired by this single stack overflow post: http://stackoverflow.com/a/834879. Because of the odd mishmash of libraries used, the implementation is about 80% C++ with 20% of C style code thrown in to play nice with curl, tidy, and boost.

The funniest part of the code at the moment is the step I call the "post-table getting step". Basically, it traverses the syntax tree generated by libxml2 to find the "juicy table" (I was kind of out of it when coming up with names at this point) which consists of the all of the posts in a given thread. The method I used to find this table is both hilarious and ugly at the same time. Basically, as libcurl is not "logged in" to TL, the bottom of the posts contains that "Please log in or register to reply." field. I search for the smallest syntax tree that contains this line AND the header to a forum post (e.g. [Username] PM ... Profile Quote...). Considering that this table is buried between dozens of layers, this method is surprisingly robust.

Often I find that what I learn during these projects ends up being more interesting than the results--and here's a brief selection of some things so far:
  • Makefiles are amazing
  • Good initial design goes a long way
  • Valgrind is your salvation in C++
  • Make will include obvious directories for libraries by default
  • Pay attention to ugly/non-intuitive include directory layouts
  • Playing nice with C-style code may mean you need to break encapsulation
  • Give the type of an argument that will be passed but no name to let the compiler know you're intentionally not using it
  • Header-only libraries exist
  • g++ seems to dislike = {0}, but will stop complaining if you use the lower level memset() instead
  • If the API poorly documents the options in a library, just fucking read the source and figure out what's available
  • HTML has ugly characters like &nbsp that will break XML parsers
  • TL's site layout is really complicated (seriously, look at the source for this page)
  • References to single characters are not null-terminated, and will riddle your strings with garbage if you expect them to be
  • Unprintable characters may ruin your day
  • If you're getting a pointer to a data structure from a function, you've got to ask yourself one question. Do you feel lucky? Was the data allocated before you called the function? If not, you better delete that shit.
  • Malloc and delete do not mix well, as do new and free. Check your API to see how you should dispose of buffers.
  • If you use std::string, expect Valgrind to find "still-reachable" leaks





*****
6581
GHOSTCLAW
Profile Blog Joined February 2008
United States17042 Posts
September 06 2013 01:57 GMT
#2
good luck ^^

On September 06 2013 10:08 Loser777 wrote:
(I don't have db access scraping is all I can do #YOLO)


5/5
PhotographerLiquipedia. Drop me a pm if you've got questions/need help.
tarpman
Profile Joined February 2009
Canada719 Posts
Last Edited: 2013-09-06 02:02:50
September 06 2013 02:01 GMT
#3
Nice work, and neat program! I've recently used libcurl and libxml2 at work, so I was interested in reading your code.

Is there a reason why you're searching the DOM manually instead of running an XPath query? I only played with xmllint for a few seconds, but I feel like something like
//td[@class="forumPost"]/text()
ought to match what you're looking for.

Concerning the struct initialization: as I understand it the usual way to do it in C++ is
TidyBuffer output = {};
which will initialize all members to their default values, rather than 0. When you just have data members it doesn't matter, but if your struct contains objects they might need to be initialized. See this Stack Overflow question for more.
Saving the world, one kilobyte at a time.
Loser777
Profile Blog Joined January 2008
1931 Posts
September 06 2013 02:21 GMT
#4
On September 06 2013 11:01 tarpman wrote:
Nice work, and neat program! I've recently used libcurl and libxml2 at work, so I was interested in reading your code.

Is there a reason why you're searching the DOM manually instead of running an XPath query? I only played with xmllint for a few seconds, but I feel like something like
//td[@class="forumPost"]/text()
ought to match what you're looking for.

Concerning the struct initialization: as I understand it the usual way to do it in C++ is
TidyBuffer output = {};
which will initialize all members to their default values, rather than 0. When you just have data members it doesn't matter, but if your struct contains objects they might need to be initialized. See this Stack Overflow question for more.

Hmm, I didn't know about that part of API for libxml2 yet--I'll have to check that out! It could potentially fix the quote problem I was having!

As for the variable initialization, it probably doesn't matter as it's just a buffer that's going to get overwritten anyway. As it's not an object, I prefer using memset. Given that the tidy implementation appears to be strictly C, I don't think the struct is going to contain any objects .
6581
Please log in or register to reply.
Live Events Refresh
Wardi Open
12:00
#57
WardiTV354
OGKoka 237
Rex82
Liquipedia
Replay Cast
10:00
Crank Gathers S2: Preliminary
Team Liquid vs Shopify RebellionLIVE!
Team Vitality vs Team Falcon
CranKy Ducklings184
LiquipediaDiscussion
[ Submit Event ]
Live Streams
Refresh
StarCraft 2
OGKoka 237
SortOf 157
Rex 82
StarCraft: Brood War
Britney 28487
firebathero 7869
Jaedong 5355
Sea 1551
EffOrt 556
Pusan 545
Stork 365
Rush 125
ToSsGirL 84
Liquid`Ret 69
[ Show more ]
Icarus 36
Movie 31
Shine 19
yabsab 15
Dota 2
Gorgc2966
Dendi527
qojqva254
XcaliburYe154
ODPixel113
420jenkins32
Counter-Strike
olofmeister1571
shoxiejesuss1098
x6flipin535
oskar168
Other Games
summit1g7483
singsing1784
B2W.Neo547
crisheroes314
Sick270
Pyrionflax221
hiko135
Lowko79
Mew2King48
Happy46
Organizations
Counter-Strike
PGL8183
StarCraft: Brood War
lovetv 13
StarCraft 2
Blizzard YouTube
StarCraft: Brood War
BSLTrovo
sctven
[ Show 12 non-featured ]
StarCraft 2
• StrangeGG 18
• AfreecaTV YouTube
• intothetv
• Kozan
• IndyKCrew
• LaughNgamezSOOP
• Migwel
• sooper7s
StarCraft: Brood War
• BSLYoutube
• STPLYoutube
• ZZZeroYoutube
Dota 2
• WagamamaTV231
Upcoming Events
CrankTV Team League
35m
Streamerzone vs Shopify Rebellion
TBD vs Team Vitality
Monday Night Weeklies
4h 35m
BSL 21
12h 35m
WardiTV Invitational
23h 35m
CrankTV Team League
1d
BASILISK vs TBD
Team Liquid vs Team Falcon
BSL 21
1d 12h
Replay Cast
1d 21h
OSC
1d 23h
CrankTV Team League
2 days
Replay Cast
2 days
[ Show More ]
The PondCast
2 days
CrankTV Team League
3 days
Replay Cast
3 days
WardiTV Invitational
3 days
CrankTV Team League
4 days
Replay Cast
4 days
BSL Team A[vengers]
5 days
Dewalt vs Shine
UltrA vs ZeLoT
BSL 21
5 days
Sparkling Tuna Cup
5 days
BSL Team A[vengers]
6 days
Cross vs Motive
Sziky vs HiyA
BSL 21
6 days
Wardi Open
6 days
Liquipedia Results

Completed

ASL Season 20
WardiTV TLMC #15
Eternal Conflict S1

Ongoing

BSL 21 Points
CSL 2025 AUTUMN (S18)
BSL 21 Team A
C-Race Season 1
IPSL Winter 2025-26
KCM Race Survival 2025 Season 4
SOOP Univ League 2025
CranK Gathers Season 2: SC II Pro Teams
PGL Masters Bucharest 2025
Thunderpick World Champ.
CS Asia Championships 2025
ESL Pro League S22
StarSeries Fall 2025
FISSURE Playground #2
BLAST Open Fall 2025
BLAST Open Fall Qual
Esports World Cup 2025
BLAST Bounty Fall 2025

Upcoming

SC4ALL: Brood War
YSL S2
BSL Season 21
SLON Tour Season 2
BSL 21 Non-Korean Championship
RSL Offline Finals
WardiTV 2025
RSL Revival: Season 3
Stellar Fest
SC4ALL: StarCraft II
META Madness #9
eXTREMESLAND 2025
ESL Impact League Season 8
SL Budapest Major 2025
BLAST Rivals Fall 2025
IEM Chengdu 2025
TLPD

1. ByuN
2. TY
3. Dark
4. Solar
5. Stats
6. Nerchio
7. sOs
8. soO
9. INnoVation
10. Elazer
1. Rain
2. Flash
3. EffOrt
4. Last
5. Bisu
6. Soulkey
7. Mini
8. Sharp
Sidebar Settings...

Advertising | Privacy Policy | Terms Of Use | Contact Us

Original banner artwork: Jim Warren
The contents of this webpage are copyright © 2025 TLnet. All Rights Reserved.