【问题标题】:Scrape articles form wsj by requests, CURL and BeautifulSoup通过请求、CURL 和 BeautifulSoup 抓取文章形成 wsj
【发布时间】:2017-07-07 07:57:51
【问题描述】:

我是 wsj 的付费会员,我尝试抓取文章来完成我的 NLP 项目。我以为我保留了会话。

rs = requests.session()
login_url="https://sso.accounts.dowjones.com/login?client=5hssEAdMy0mJTICnJNvC9TXEw3Va7jfO&protocol=oauth2&redirect_uri=https%3A%2F%2Faccounts.wsj.com%2Fauth%2Fsso%2Flogin&scope=openid%20idp_id&response_type=code&nonce=18091b1f-2c73-4a93-ab10-77b0d4d4f9d3&connection=DJldap&ui_locales=en-us-x-wsj-3&mg=prod%2Faccounts-wsj&state=NfljSw-Gz-TnT_I6kLjnTa2yxy8akTui#!/signin" 
payload={
    "username":"xxx@email",
    "password":"myPassword",
}
result = rs.post(
    login_url, 
    data = payload, 
    headers = dict(referer=login_url)
)

我要解析的文章。

r = rs.get('https://www.wsj.com/articles/singapore-prime-minister-lee-rejects-claims-he-misused-state-powers-in-family-feud-1499094761?tesla=y')

然后我发现html仍然是非会员的

我还尝试了另一种方法,登录后使用 CURL 保存 cookie

curl -c cookies.txt -I "https://www.wsj.com"
curl -v cookies.txt "https://www.wsj.com/articles/singapore-prime-minister-lee-rejects-claims-he-misused-state-powers-in-family-feud-1499094761?tesla=y" > test.html

结果是一样的。

我不太熟悉浏览器背后的身份验证机制。有人可以解释为什么上述两种方法都失败了,我应该如何解决它以实现我的目标。非常感谢。

【问题讨论】:

    标签: curl web-crawler python-requests


    【解决方案1】:

    您的尝试失败了,因为使用的协议是oauth2.0。这不是基本身份验证。

    这里发生了什么:

    • 在调用登录 URL https://accounts.wsj.com/login 时会在服务器端生成一些信息:connection & client_id
    • 提交用户名/密码时,URL https://sso.accounts.dowjones.com/usernamepassword/login 被调用,需要一些参数(之前的connection & client_id + oauth2 的一些静态参数:scoperesponse_typeredirect_uri 李>
    • 从先前的登录调用收到响应,该响应提供自动提交的表单。此表单有 3 个参数 wawresultwctxwresultJWT)。此表单执行对 https://sso.accounts.dowjones.com/login/callback 的调用以检索带有代码参数的 URL,例如 code=AjKK8g0pZZfvYpju
    • 调用 URL https://accounts.wsj.com/auth/sso/login?code=AjKK8g0pZZfvYpju 检索具有有效用户会话的 cookie

    使用curlgreppupjq的bash脚本:

    username="user@gmail.com"
    password="YourPassword"
    
    login_url=$(curl -s -I "https://accounts.wsj.com/login")
    connection=$(echo "$login_url" | grep -oP "Location:\s+.*connection=\K(\w+)")
    client_id=$(echo "$login_url" | grep -oP "Location:\s+.*client_id=\K(\w+)")
    
    #connection=$(echo "$login_url" | gawk 'match($0, /Location:\s+.*connection=(\w+)&/, data) {print data[1]}')
    #client_id=$(echo "$login_url" | gawk 'match($0, /Location:\s+.*client_id=(\w+)&/, data) {print data[1]}')
    
    rm -f cookies.txt
    
    IFS='|' read -r wa wresult wctx < <(curl -s 'https://sso.accounts.dowjones.com/usernamepassword/login' \
          --data-urlencode "username=$username" \
          --data-urlencode "password=$password" \
          --data-urlencode "connection=$connection" \
          --data-urlencode "client_id=$client_id" \
          --data 'scope=openid+idp_id&tenant=sso&response_type=code&protocol=oauth2&redirect_uri=https%3A%2F%2Faccounts.wsj.com%2Fauth%2Fsso%2Flogin' | pup 'input json{}' | jq -r 'map(.value) | join("|")')
    
    # replace double quote ""
    wctx=$(echo "$wctx" | sed 's/&#34;/"/g')
    
    code_url=$(curl -D - -s -c cookies.txt 'https://sso.accounts.dowjones.com/login/callback' \
         --data-urlencode "wa=$wa" \
         --data-urlencode "wresult=$wresult" \
         --data-urlencode "wctx=$wctx" | grep -oP "Location:\s+\K(\S*)")
    
    curl -s -c cookies.txt "$code_url"
    
    # here call your URL loading cookies.txt
    curl -s -b cookies.txt "https://www.wsj.com/articles/singapore-prime-minister-lee-rejects-claims-he-misused-state-powers-in-family-feud-1499094761?tesla=y"
    

    【讨论】:

    • 我在网络期间查看标头并复制这些 cookie,它可以工作。您的解释使网络背后发生的事情更加清楚
    猜你喜欢
    • 2022-01-18
    • 2022-12-04
    • 2020-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-21
    • 1970-01-01
    相关资源
    最近更新 更多