Scraping youtube mix playlist id for a video - node.js

So here is what I am trying to do:
The app in question that this problem is regarding is here: https://github.com/viperfx/ng-juketube, to give everyone some context. So I am loading a youtube video in the background using the youtube Iframe API giving it a youtube video id. That works well. Next, I want to find out the playlist ID of the youtube mix's that appear sometimes on the sidebar.
Current solution:
I am using nodejs in the backend to scrape the youtube video page, and then look in the sidebar for the string 'Youtube Mix'. When I am running my server locally this works well. However when I am running the app from heroku I do not get the same results (as in a mix does not show up) because I am assuming the youtube server and the IP address I have are affecting youtube mix from showing up.
So my question is how can I obtain the youtube mix playlist id using the client (browser) rather than the server?
I have tried things like trying to load the youtube page as an iframe - does not work. iframes only allowed for /embed*

So here is how I solved this issue.
Using a service called http://www.corsproxy.com/ I was able to scrape youtube and get the playlist id using client side code. Here is a snippet from my code showing the solution:
$.get('http://www.corsproxy.com/www.youtube.com/watch?v='+newVal.videoId,function(response) {
var doc = new DOMParser().parseFromString(response, 'text/html');
$scope.mixId = doc.querySelector('.related-playlist').getAttribute('href').split('list=')[1];
$scope.$apply();
});

Related

How to get challenge key from a target website using geetest captcha

So I am scraping data from a target website using puppeteer.
Target website used geetest captcha, for anti-captcha, I am using 2capcta service,
on their documentation, it's mentioned that we need to get the challenge key every time.
From that the problem begins, target website has embedded the challenge key under
<Iframe>
<Html>
<head>
<script>
when accessing the iframe through DOM elements throw me a CORS error.
I have tried another way also which is available on the scraper box link is below
https://scraperbox.com/blog/solving-a-geetest-slider-captcha-with-puppeteer
it throws me no selector '[aria-label="Click to verify"]' found
it tried the codegrepper way link is below
https://www.codegrepper.com/code-examples/whatever/puppeteer+get+network+requests
throw me on console.error().
Any help would be appreciated to bypass geetest captcha
let me know also if my question is unclear.
Thank you so much for the answer,
so with the response by the above gentleman, the final solution is
when you load your page through puppeteer
await page.waitForSelector('iframe');
this will wait till the time iframe is loaded, now for me the target website has use the iframe with hash link to access it
const elementHandle = await page.$('iframe');
const frame = await elementHandle.contentFrame();
now the frame will have access to your iframe page, so you use the rest same like
await frame.waitForSelector("your selector")

Google Action - playing youtube video on google hub

How can I play a specific Youtube Video on my Google Hub via Google Actions? I know I can use a Basic Card to display images and text and even a link (although that link does not show up on the HUB)
I specifically want to be able to trigger or to play a youtube video on my Google Hub.
Actions are not able to start playing video content. Media responses are only for audio.
I have a similar need. After a chat with an action on google, I want to play user requested youtube videos (chains-of) on a local "big screen" (TV-like / PC).
A workaround solution could be:
you realize an action that select one or more videos.
The action act also as a server for a client described here below
The action communicate (SSE, websocket, HTTP...) with a client browser page containing a javascript small program that dynamically visualize the video (id sent via SSE client-server communication)
Here below the rough js script (I'm not a web developer); that just gives you the idea:
<script language="javascript">
function loadVideoWithId(id) {
const tvEmbedMode = "embed/" //"tv#/watch?v="
const url = `https://www.youtube.com/embed/${id}?fs=1&autoplay=1&loop=1` //
const iframe = `<iframe src="${url}" width="1600" height="900" allowFullScreen="allowFullScreen" frameBorder="0" />`
document.write(iframe)
}
loadVideoWithId('hHW1oY26kxQ')
</script>

detect youtube full screen in chrome extension

I have a Chrome extension, which detects Youtube videos and gets their category via the Youtube API as follows:
background.js
chrome.webRequest.onBeforeRequest.addListener(function(details) {
var PageInfo = new URL(url);
if(PageInfo.host=="www.youtube.com")
getCategory(PageInfo); //returns category number via the Youtube API
});
The problem I'm facing is that this does not work if Youtube is in full screen mode. For example after I load a video normally, I change to full screen and pick a video from the suggested videos after the initial one has finished playing. I then cannot get the extension to correctly pick up that new video.
Any tips would be appreciated. Thanks.

Google analytics stores username and password as a part of url

Issue Context:
I am using meteor js for a mobile app.
I have hooked it up with google analytics calls and basically I am using two type of calls:
Screen views
Events
Screen views are just fine, but I'm facing an issue with the events.
When I go to Behavior -> Events -> Screens, in the google analytics dashboard, I can see the URL of every page that has triggered an event under the Screen Name column. My problem is that the page URLs for my login page look something like this:
meteor.local/login?username=*******&password=+++++++&rememberMe=on
Where ******* is an actual username and +++++++ is the corresponding password!
Reason:
Since I have to share this analytics account with multiple people, I do not want this information to be available over here.
Clues:
CLUE 1:
I used to do GET http calls, but I have changed them all to POST and it still has not fixed the issue as I expected it not to pass plain parameters through URL anymore.
CLUE 2:
I've noticed that the default google analytics js framework is working with http and not https. I was wondering if it is calling the analytics server with a GET as well. If so, is there anyway to change that?
CLUE 3:
Here is how I am initiating the GA instance:
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o),
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', googleKey, 'auto');
CLUE 4:
I have also noticed that these URLs are getting captured very occasionally. E.g. in the pas 12,500 unique events (about 30,000 total events) it has captured just 9 URLs with the username and password. The remaining 12,491 events have
meteor.local/login
OR
meteor.local/--
OR
localhost/--
as the Screen Name.
CLUE 5:
I have also put 4 "search and replace" global filters on the analytics account to search for this string
meteor.local/.*
and replace it with this one
meteor.local/concealedURI
This does not seem to be working either.
I have added this filter on 4 different fields (Since I still really don't know where the URLs are coming from):
Host Name
Page Title
Referral
Request URI
CLUE 6:
This is how I am calling the GA instance to send the event:
ga('send', 'event', 'button', 'click', eventName);
Okay. So, I had to run a lot of experiments and try out different things to solve this issue.
After trying all the things that I have described in the question, I finally found a way to address this problem.
The main cause of this problem was that I was using a google analytics account set to track an App, to capture the data from an app that was built with meteor js (which basically utilizes cordova).
Using meteor means that my app's screens are actually web pages rendered as a mobile app. It seems like meteor uses URLs to navigate through these screens.
On the other hand, google analytics looks at (and captures) the screen name of an app's page, when an event is triggered from that page. In native apps this screen name will be something similar to "About us", "Contact Us", "Home", etc.
Now since a meteor app is not the same, the screen name returned by meteor is actually the URL of the page that has triggered the event.
This does not have anything to do with the http calls (Whether or not they are GET or POST), because it is the local URL used by meteor for navigating that is being passed down to google analytics and not any http calls.
Solutions
1.
If I had the google analytics account set as a web page tracker, I could have access to "Exclude URL Query Parameters" field and I could potentially exclude username and password as was suggested by #Mike and #PhilipPryde in the comments.
However, I needed to use google analytics set as an app tracker. So, this did not work for me.
Failed
2.
I did put a filter on the whole view in the google analytics and searched for meteor.local/.* and replaced that with hiddenURL. The filters on
Host Name
Page Title
Referral
Request URI
did not work.
But when I put the same filter on
Screen Label
field, it worked.
However, this only looked at the screen names returned by screen view hits and not the event. Thus, this did not actually solve my issue either.
Failed
Finally, I had to do this:
There is a method call on GA instance that lets you set different options up. I ended up using this:
ga('set', 'screenName', 'hiddenURL');
This changed the screen name to "hiddenURL". So, I used this before every event and it worked for me.
My code for sending events to google analytics looked like this:
ga('set', 'screenName', 'hiddenURL');
ga('send', 'event', 'button', 'click', eventName);
PS:
This changes the screen name that was showing up in real-time reports of google analytics to "hiddenURL", whenever someone triggered an event. But, it changes back to a screen name as soon as they go to another page. So, it would not also mess with any of your screen view data either, since it is not being captured as a screen view.
Of course that is because, I pass the screen name to my GA instance every time I send a screen view. So it looks like this:
sendScreenViewToGA = function (screenName) {
ga('send', 'screenview', {
'appName': 'Something',
'screenName': screenName,
'appVersion': x.x
});
}
If I had used the screen name, that is being set on the environment tight now, I would have ended up with all my screen names in analytics set to "hiddenURL".
I really hope this post will help others with same issues and save them some time.

Add title to vimeo video through nodejs vimeo api?

I am writing an application to upload a video file to vimeo .
The problem is the title is always set to "Untitled"!
Is there any way to set the title of the video while uploading through the api?
I am using This api
Have a look
Docs for PATCH-ing your video post-upload are here.
Name and title are one and the same. The docs look a little confusing right now so I'll clean those up.
In node, the code looks like this
var response = lib->request({method:'PATCH', path:video_uri, query:{name:'New Name'}});

Resources