【问题标题】:How to find all the JavaScript requests made from my browser when I'm accessing a site访问网站时如何查找浏览器发出的所有 JavaScript 请求
【发布时间】:2020-03-11 00:32:36
【问题描述】:

我想抓取使用 requests 和 bs4 的 LinkedIn 的内容,但我在登录后加载页面的 JavaScript 遇到问题(我没有获得主页直接),我不想使用 Selenium

这是我的代码

import requests
from bs4 import BeautifulSoup

class Linkedin():
    def __init__(self, url ):
        self.url = url
        self.header = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) "
                                 "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36"}

    def saveRsulteToHtmlFile(self, nameOfFile=None):
        if nameOfFile == None:
            nameOfFile ="Linkedin_page"
        with open(nameOfFile+".html", "wb") as file:
            file.write(self.response.content)

    def getSingInPage(self):
        self.sess = requests.Session()
        self.response = self.sess.get(self.url, headers=self.header)
        soup = BeautifulSoup(self.response.content, "html.parser")
        self.csrf = soup.find(attrs={"name" : "loginCsrfParam"})["value"]

    def connecteToMyLinkdin(self):
        self.form_data = {"session_key": "myemail@mail.com",
                     "loginCsrfParam": self.csrf,
                     "session_password": "mypassword"}
        self.url = "https://www.linkedin.com/uas/login-submit"
        self.response = self.sess.post(self.url, headers=self.header, data=self.form_data)


    def getAnyPage(self,url):
        self.response = self.sess.get(url, headers=self.header)




url = "https://www.linkedin.com/"

likedin_page = Linkedin(url)
likedin_page.getSingInPage()
likedin_page.connecteToMyLinkdin() #I'm connected but java script still loading 
likedin_page.getAnyPage("https://www.linkedin.com/jobs/")
likedin_page.saveRsulteToHtmlFile()

我需要帮助在不使用 Selenium 的情况下传递 javascript 负载...

【问题讨论】:

    标签: javascript python python-3.x python-2.7 python-requests


    【解决方案1】:

    虽然在技术上可以模拟所有来自 Python 的调用,但在 LinkedIn 这样的动态页面上,我认为它会相当乏味和脆弱。

    无论如何,在您打开 LinkedIn 之前,您应该在浏览器中打开“开发者工具”并查看流量情况。您可以过滤来自 Javascript 的请求(在 Firefox 中,过滤器称为 XHR)。

    然后,您将在代码中模拟必要/有趣的请求。好处是服务器通常将结构化数据返回到 Javascript,例如 JSON。因此,您不需要做太多的 HTML 解析。

    如果您发现这种方式进展不大(这实际上取决于特定站点),那么您可能必须使用 Selenium 或其他替代方法,例如:

    【讨论】:

    • 如何在浏览器中使用 python 获取此请求
    • 与您在现有代码中发出请求的方式相同:通过requests.Session。但是你必须复制浏览器的功能。
    • 不明白你的意思。我期望找到一些自动方法来回顾所有的java请求;不要手动声明它们。
    • 在这种情况下,我认为你真的需要运行 Javascript 的东西。 Puppeteer、Selenium 或类似的。为什么要避免它?
    • 那就试试 Puppeteer。此外,无头运行浏览器(没有真实窗口)可能会加快速度。正如@Adarsh Punj 所写,您也许可以为当前版本的 LinkedIn 提供一些纯 Python 解决方案。但总的来说,如果不实际运行 Javascript 代码,您无法预测请求。
    【解决方案2】:

    您应该手动发送所有 XHR 和 JS 请求 [在您在登录期间创建的同一会话中]。此外,传递请求标头中的所有字段(从网络工具复制)。

    self.header_static = {
            'authority': 'static-exp2.licdn.com',
            'method': 'GET',
            'path': '/sc/h/c356usw7zystbud7v7l42pz0s',
            'scheme': 'https',
            'accept': '*/*',
            'accept-encoding': 'gzip, deflate, br',
            'accept-language': 'en-GB,en;q=0.9,en-US;q=0.8,hi;q=0.7,la;q=0.6',
            'cache-control': 'no-cache',
            'dnt': '1',
            'pragma': 'no-cache',
            'referer': 'https://www.linkedin.com/jobs/',
            'sec-fetch-mode': 'no-cors',
            'sec-fetch-site': 'cross-site',
            'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Mobile Safari/537.36'
            }
    
    def postConnectionRequests(self):
            urls = [
            "https://static-exp2.licdn.com/sc/h/62mb7ab7wm02esbh500ajmfuz",
            "https://static-exp2.licdn.com/sc/h/mpxhij2j03tw91bpplja3u9b",
            "https://static-exp2.licdn.com/sc/h/3nq91cp2wacq39jch2hz5p64y",
            "https://static-exp2.licdn.com/sc/h/emyc3b18e3q2ntnbncaha2qtp",
            "https://static-exp2.licdn.com/sc/h/9b0v30pbbvyf3rt7sbtiasuto",
            "https://static-exp2.licdn.com/sc/h/4ntg5zu4sqpdyaz1he02c441c",
            "https://static-exp2.licdn.com/sc/h/94cc69wyd1gxdiytujk4d5zm6",
            "https://static-exp2.licdn.com/sc/h/ck48xrmh3ctwna0w2y1hos0ln",
            "https://static-exp2.licdn.com/sc/h/c356usw7zystbud7v7l42pz0s",
            ]
    
            for url in urls:
                self.sess.get(url,headers=self.header_static)
                print("REQUEST SENT TO "+url)
    
    

    我在保存 HTML 内容之前调用了postConnectionRequests() 函数,并收到了完整的页面。 希望这会有所帮助。

    【讨论】:

    • 这是否意味着我必须手动抓取所有请求?.
    • 如果你不执行Javascript,那么一般来说,是的。
    • 除非您在 HTML 文档本身中找到这些链接,否则您必须手动收集这些链接。虽然这样做不是很长,因为只有大约 10 个这样的链接。您可以转到 /jobs/、/in/ 等,并从 Network 选项卡中收集这些链接。
    【解决方案3】:

    XHR 由JavaScript 发送,Python 在使用 requests 和 beautifulsoup 获取页面时不会运行 JavaScript 代码。 Selenium 之类的工具会加载页面并运行 JavaScript。你也可以使用Headless Browsers

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-17
      • 1970-01-01
      • 1970-01-01
      • 2018-01-11
      • 2019-04-02
      • 1970-01-01
      • 2018-06-16
      相关资源
      最近更新 更多