Author Topic: Screenscraping - A technique to find the vpid  (Read 193 times)

0 Members and 1 Guest are viewing this topic.

Offline Ed

  • Full Member
  • ***
  • Posts: 122
    • View Profile
Screenscraping - A technique to find the vpid
« on: July 03, 2017, 09:29:06 PM »
When I am completely stuck, I use the following website to look up url's for the 'Listen Again' programmes on the radio iPlayer:

  http://www.iPlayerConverter.co.uk/convert.aspx

I can use ffmpeg.exe to download high quality streams from these url's (higher bitrates than I typically get from using programs such as get_iplayer, e.g. 320 kbps and 384 kbps streams).

It used to be trivial to use iPlayerConverter.co.uk because all it needed was the 8-digit PID (Programme ID) included in the Listen Again page's url.

But recently iPlayerConverter.co.uk changed over to using the vpid instead of the pid. I thought it was still trivial to get the vpid because, when you play the 'Listen Again' radio show, you can right-click on the playing window in the browser, and a pop-up window opens and displays both the PID and the VPID.

Now, however, the iPlayer has disappeared behind a pay-wall, and you can't play the show, so can't right-click on the playing window. (Yes, I know no money changes hands, but the technology being deployed against us is nonetheless what's known in the trade as a 'paywall'.)

Yes, it is still trivial to get the vpid. You can still play the show in older browsers: if you play it in Internet Explorer 8, the newer javascript on the iplayer website is ignored by the browser, which only understands older forms of javascript. So the show plays, and the player window appears, and can be right-clicked.

And in any browser, you can view the page source and do a 'find' search for "vpid" to find it.

I thought it would be better to write a short batch file routine to extract the 8-digit vpid from the page automatically, using just the ordinary PID. So here it is. The only contribution made by the user is to insert the PID (replacing the example PID shown as a row of 8 zero's).

This is a demo script, really, because it can readily be adapted to extract any desired information from a .html web page (that is, an ordinary webpage, one which does not use xml). The javascript runs in Internet Explorer, and downloads the target webpage specified, as a text string, which it then searches: using a javascript technique called Regular Expressions to specify the text to be extracted. It then displays any matching text found.


Click 'Select' to highlight the code, then copy-and-paste it into a plain text file with the file extension .bat instead of .txt (e.g. vpid.bat). Then open the .bat file (using, say, Notepad.exe), and replace the 8 zero's with the actual 8-digit PID of the target iplayer page. Then double click the .bat file to run it.



Code: [Select]
@echo off

::  *** Get the VPID : BBC Radio on-demand ***

::  ** Programme ID **
SET PID=00000000

::  -------------------------------------------------------------------------------------------------------------------------------------------  ::

::  *** User Variables ***
    SET temp_dir=C:\\Users\\dg\\AppData\\Local\\Temp

::  -------------------------------------------------------------------------------------------------------------------------------------------  ::

ECHO ^<html^>                                                                                                                    > %temp%\temp.htm
ECHO ^<head^>                                                                                                                   >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO ^<title^>Download BBC iPlayer HTML page and extract Text^</title^>                                                         >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO ^<SCRIPT language="javascript" type="text/javascript"^>                                                                    >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO // Target HTML file's URL address                                                                                          >> %temp%\temp.htm
ECHO    var url = "http://www.bbc.co.uk/programmes/%PID%" ;                                                                     >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO window.open('','_self'); // This prevents the browser window prompting before closing                                      >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO var http_request = false;                                                                                                  >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO function makeRequest(url) {  // URL = iPlayer page                                                                         >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO   http_request = false;                                                                                                    >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO   try {                                                                                                                    >> %temp%\temp.htm
ECHO     http_request = new ActiveXObject("Msxml2.XMLHTTP");                                                                    >> %temp%\temp.htm
ECHO   } catch (e) {                                                                                                            >> %temp%\temp.htm
ECHO     try {                                                                                                                  >> %temp%\temp.htm
ECHO       http_request = new ActiveXObject("Microsoft.XMLHTTP");                                                               >> %temp%\temp.htm
ECHO     } catch (e) {}                                                                                                         >> %temp%\temp.htm
ECHO   }                                                                                                                        >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO   if (!http_request) {                                                                                                     >> %temp%\temp.htm
ECHO     alert ('Giving up - Cannot create an XMLHTTP instance');                                                               >> %temp%\temp.htm
ECHO     return false;                                                                                                          >> %temp%\temp.htm
ECHO   }                                                                                                                        >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO   http_request.onreadystatechange = alertContents;                                                                         >> %temp%\temp.htm
ECHO   http_request.open('GET', url, true);                                                                                     >> %temp%\temp.htm
ECHO   http_request.send(null);                                                                                                 >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO }  // Close FUNCTION                                                                                                       >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO function alertContents() {                                                                                                 >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO   if ( http_request.readyState == 4 ) {                                                                                    >> %temp%\temp.htm
ECHO     if ( http_request.status == 200 ) {                                                                                    >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO        var fso  = new ActiveXObject("Scripting.FileSystemObject");                                                         >> %temp%\temp.htm
ECHO        var fh  = fso.CreateTextFile("%temp_dir%\\%PID%.html",true);         // Create Text File                            >> %temp%\temp.htm
ECHO        var fh1 = fso.CreateTextFile("%temp_dir%\\%PID%_vpid.txt",true);     // Create Text File                            >> %temp%\temp.htm
ECHO        var fh2 = fso.CreateTextFile("%temp_dir%\\%PID%_vpid_2.txt",true);   // Create Text File                            >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO        // Save contents of HTML page to text file as a String                                                   // line 50 >> %temp%\temp.htm
ECHO           fh.WriteLine( "<base href='http://www.bbc.co.uk'>" );             // Add BBC domain's href address               >> %temp%\temp.htm
ECHO           fh.WriteLine( http_request.responseText );                        // Add HTML contents of target webpage         >> %temp%\temp.htm
ECHO           // alert ( http_request.responseText );                                                                          >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO        // Use RegEx [Regular Expression] to find data in responseText (HTML)                                               >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO           // Input String (HTML from target URL)                                                                           >> %temp%\temp.htm
ECHO              var input = http_request.responseText;                          // Input                                      >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO           // Define the Pattern                                              // Pattern                                    >> %temp%\temp.htm
ECHO           // 8 literals + 8 chrs (mixed letters and digits) + 1 literal      // Example: "vpid":"b006bm2h"                 >> %temp%\temp.htm
ECHO              var pattern = /"vpid":"[A-Z0-9]{8}"/gi;                                                                       >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO           // Create OUTPUT string holding ALL matches                                                                      >> %temp%\temp.htm
ECHO              var str1 = input.match(pattern);                                // Match String with Pattern                  >> %temp%\temp.htm
ECHO              // alert ( str1 );                                                                                            >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO           // Save the data to a text file -                                                                                >> %temp%\temp.htm
ECHO              fh1.WriteLine( str1 );                                          // %PID%_vpid.txt                  // line 70 >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO           // Adjust the data -                                                                                             >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO              // Replace some text                                                                                          >> %temp%\temp.htm
ECHO                 var str2 = fso.OpenTextFile("%temp_dir%\\%PID%_vpid.txt");   // Open a text file                           >> %temp%\temp.htm
ECHO                 var str3 = str2.ReadAll();                                   // Read file's contents into a variable       >> %temp%\temp.htm
ECHO                 var str4 = str3.replace(/^"/g, "").replace(/^:/g, ": ");     // Replace all quotes and semicolons          >> %temp%\temp.htm
ECHO              // var str4 = str3.replace(/^"/g, "").replace(/^,/g, "\n");     // Replace all quotes and all commas          >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO              // Split the data into sections seperated by the specified symbol                                             >> %temp%\temp.htm
ECHO                 var str5 = str4.split(",");                                                                                >> %temp%\temp.htm
ECHO                 // alert ( str5[0] ) ;                                                                                     >> %temp%\temp.htm
ECHO                 // alert ( str5[1] ) ;                                                                                     >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO              // Save the adjusted data to a text file -                      // Save to %PID%_vpid_2.txt                   >> %temp%\temp.htm
ECHO                 fh2.WriteLine( "pid:  %PID%" );                                                                            >> %temp%\temp.htm
ECHO                 fh2.WriteLine( str5[0] );                                    // Save only the FIRST (discard str5[1])      >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO     } else { alert ('There was a problem with the request') };                                                             >> %temp%\temp.htm
ECHO   }                                                                                                                        >> %temp%\temp.htm
ECHO }     // Close FUNCTION                                                                                                    >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO ^</SCRIPT^>                                                                                                                >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO ^</head^>                                                                                                                  >> %temp%\temp.htm
ECHO.                                                                                                                           >> %temp%\temp.htm
ECHO ^<body onload="makeRequest(url);setTimeout('window.close()',4000)"^> ^</body^>                                             >> %temp%\temp.htm
ECHO ^</html^>                                                                                                                  >> %temp%\temp.htm

::  The function setTimeout gives TEMP.HTM enough time to access the Internet
::  before the scripts in it run (which need the data drawn from the Internet)

::  -------------------------------------------------------------------------------------------------------------------------------------------  ::

::  *** Run temp.htm ***
"C:\Program Files (x86)\Internet Explorer\IEXPLORE.EXE" %temp%\temp.htm

::  *** Open file : VPID ***
START ""  "C:\Windows\SYSTEM32\Notepad.exe" "%temp_dir%\\%PID%_vpid_2.txt"





« Last Edit: July 03, 2017, 09:59:53 PM by Ed »

Offline Truthyness

  • Administrator
  • Hero Member
  • *****
  • Posts: 8,270
    • View Profile
Re: Screenscraping - A technique to find the vpid
« Reply #1 on: July 08, 2017, 08:40:05 PM »
Gosh I haven't yet come up against a Beeb iPlayer paywall! Sounds hideous. Thanks to your posts at least now I am psyched up! 8)

A commitment to Mod\'nAdminlyness: I understand that  r-e-s-i-s-t-a-n-c-e  *i - s*    f-u-t-i-l-e.
I shall not be starc

Offline Ed

  • Full Member
  • ***
  • Posts: 122
    • View Profile
Re: Screenscraping - A technique to find the vpid
« Reply #2 on: July 09, 2017, 11:56:20 PM »
I'm running Firefox 39 as my browser on one computer, and Internet Explorer 8 on a laptop. Both computers are Windows 7 64-bit.

When I open an iplayer 'Listen Again' page, and try to play the radio show, if I'm using Firefox I'm blocked by the paywall. But if I'm using IE8, I simply don't see any paywall.

So I think that everyone will have a different experience, depending on which browser - perhaps even which version of that browser - they are using. And it seems to be the older browsers which fare best, probably because the paywall uses a modern, new type of javascript which some older browsers can't recognise.

As I say, I'm using Windows 7. It will be interesting to hear from people who are on Windows 8 or Windows 10, as to whether that makes any difference.


Offline Ed

  • Full Member
  • ***
  • Posts: 122
    • View Profile
UPDATE -
« Reply #3 on: September 11, 2017, 04:09:06 AM »
The Greasemonkey script - which I've mentioned in other threads on Beebotron - gets the DASH url of the radio show (needed to play or download that show) from this webpage:

http://open.live.bbc.co.uk/mediaselector/5/select/version/2.0/mediaset/pc/vpid/00000000


The script substitutes the vpid of the radio show in question for the 8 zero's. (The acronym 'vpid' stands for 'Version Programme ID').

To find the 8-digit vpid, start the On-demand radio show playing on the BBC iPlayer page, and right-click on the player window. The vpid is included in the second line of the information box which pops up (usually the 3rd item).

On some BBC webpages, the vpid is sometimes named the verpids.


Here's an example of what an actual DASH url looks like for an on-demand radio show:

http ://aod-dash-uk-live.akamaized.net/usp/auth/vod/piff_abr_full_audio/
0a312b-b0027l6w/vf_b0027l6w_9ea0e33c-352a-4f8c-8b48-a4772c9a17ec.ism/
pc_hd_abr_v2_uk_dash_master.mpd?__gda__=1504059651_af4dc1f32e4addcd9a515b8b64284d4a


The program YouTube-dl.exe can download this type of url, and the program VLC Media Player can play this type of url.



The above procedure is also how to find the URL for an iplayer on-demand TELEVISION show.

Here's an example from a recent repeat of "Dad's Army" on BBC2:

http://open.live.bbc.co.uk/mediaselector/5/select/version/2.0/mediaset/pc/vpid/b000s29y

That's an example of the url which the program Get_iPlayer uses to download tv shows from the iPlayer website,  without the need to sign-in.
« Last Edit: September 11, 2017, 04:31:54 AM by Ed »