1

I am building a web browser and i want to enable ad blocking in it. I have read multiple answers, but I havent been able to implement it successfully.

I have successfully loaded the adFilter and ad matching works fine.

I think this has something to do with the networkAccessManager but I am unable to figure out how.

This is my class that inherits the QNetworkAccessManager class

class NetworkManager(QNetworkAccessManager):
def __init__(self):
    super().__init__()
    self.adblocker = Filter(open('easylist.txt', encoding="utf8"))
    self.finished.connect(self._finished)

def createRequest(self, op, request, device=None):
    url = request.url().toString()
    if self.adblocker.match(url):
        print('blocking url, ', url)
        # block ads here
    else:
        print('good to go', url)
        return QNetworkAccessManager.createRequest(self, op, request, device)

def examine(self, url):
    self.get(QNetworkRequest(QUrl(url)))

def _finished(self, reply):
    headers = reply.rawHeaderPairs()
    headers = {str(k):str(v) for k,v in headers}
    content_type = headers.get("Content-Type")
    url = reply.url().toString()
    status = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
    cookies = headers.get("Set-Cookie")
    logger.log('{} --- {} --- {}'.format(str(status), url, content_type), 2)

I tried overriding the createRequest method. The ads are getting detected but those ad requests are not actually getting blocked.

How do i achieve this.

  • Is the problem that your `print('blocking url, ', url)` branch never executes, or that the code you wrote there in place of `# block ads here` isn't working, or that you expect that just not getting into the `else` ought to be sufficient but it isn't? – abarnert Mar 17 '18 at 18:41
  • 3
    If you're using QWebEngineView, the QNetworkAccessManager class will be no use at all. You need to use [QWebEngineUrlRequestInterceptor](https://doc.qt.io/qt-5/qwebengineurlrequestinterceptor.html#details). – ekhumoro Mar 17 '18 at 20:55
  • @abarnert The print statement works. I did mention that the ads are getting detected. The problem is that I dont know how to close such network requests. And the createRequest method excpects a NetworkReply object in return, so i need to write code in place of the comment that is to figured out – Praneet Mehta Mar 18 '18 at 05:05
  • @ekhumoro can you please suggest the relevant code edits? – Praneet Mehta Mar 18 '18 at 05:09
  • @PraneetMehta. No, because I have no idea how you are intending to use it. Are you using QWebEngineView or not? – ekhumoro Mar 18 '18 at 05:19
  • @ekhumoro Yes I am and I successfully implemented the ad blocker using QWebEnginePage class by overriding the acceptNavigationRequest method. Thanks for your help. – Praneet Mehta Mar 19 '18 at 14:43

1 Answers1

1

This is how I finally implemented the AdBlocker. You just need to override the acceptNavigationRequest method in The QWebEnginePage class. This is how I implemented it

class WebPage(QWebEnginePage):

    adblocker = Filter(open('easylist.txt', encoding="utf8"))

    def __init__(self, parent=None):
        super().__init__(parent)

    def acceptNavigationRequest(self, url,  _type, isMainFrame):

        urlString = url.toString()
        resp = False
        resp = WebPage.adblocker.match(url.toString())

        if resp:
            print("Blocking url --- "+url.toString())
            return False
        else:
            print("TYPE", _type)
            return True

        return QWebEnginePage.acceptNavigationRequest(self, url,  _type, isMainFrame)