Week 3 of the NFL season has ended and it’s around week 3 or 4 that SRS resolves, so I started trying to download data into my database. Oh, guess what, my old scraper is blocked. So, the fix is nflfastR.com, as it has data, dating back many years, and in that data are EPA based results. The kinds of things you can analyze from that data set are well documented on Twitter by @benbaldwin, so look at some of his tweets to see all its uses. Next, I spent maybe 15 minutes asking AI how I could get these data, and to a large extent, it wrote the Perl I need to get the data I want. Of course, the code broke, and I spent some time fixing it.
Below is the fixed code that AI gave me. It’s hacky, but shows that nflfastR can be accessed by a variety of tools, not just R.
#! /usr/bin/perluse ;use ;use ::;use ::;use :::: qw(gunzip $GunzipError);use ::;# Define target year/seasonmy $target_year = 2026;# Primary nflverse URL for schedules and scoresmy $url = 'https://github.com';my $url = 'https://github.com/nflverse/nflverse-data/releases/download/pbp/play_by_play_' . $target_year . '.csv.gz';print $url,"\n";# 1. Initialize Mechanize and fetch the filemy $mech = ::->new( => 1 );print "Fetching game score data from nflverse...\n";$mech->($url);# Extract raw downloaded contentmy $raw_content = $mech->;# 2. Decompression handling# If the server returned gzip or the file signature suggests gzip, decompress it.my $decompressed_content;if ( $raw_content =~ /^\x1f\x8b/ ) { # Gzip magic number check print "Decompressing gzipped data layer...\n"; \$raw_content => \$decompressed_content or die "Decompression failed: $GunzipError\n";} else { $decompressed_content = $raw_content;}# print $decompressed_content;# exit 7;my $csv = ::->new({ => 1, => 1, # headers => 'auto' # Automatically treats the first line as columns});open my $fh, '<', \$decompressed_content or die "Failed to open memory buffer: $!";$csv->($fh);my @games_array;print "Filtering game scores for the $target_year season...\n";# 4. Parse line-by-line and load into arraywhile ( my $row = $csv->($fh) ) { # Skip rows that don't match our target season year next unless $row->{season} == $target_year; # Construct individual game object pushing required fields push @games_array, { => $row->{game_id}, => $row->{season}, => $row->{week}, # The requested week field => $row->{home_team}, => $row->{away_team}, => $row->{home_score}, => $row->{away_score}, => $row->{game_type}, # REG or POST season };}close $fh;print "Successfully loaded " . scalar(@games_array) . " games into the array.\n\n";print "Sample Data (First 2 entries):\n";print ( [ @games_array[0..1] ] );
Totally unrelated to all this, but as I have retired, I am writing a novel here: https://www.royalroad.com/fiction/184090/reborn-as-an-orc

