【问题标题】:A bug when creating parameters for request.get为 request.get 创建参数时的错误
【发布时间】:2020-09-15 20:30:14
【问题描述】:

我正在迭代这个网站并尝试抓取新闻文章的链接。 https://www.usnews.com/search?q=China%20COVID-19#gsc.tab=0&gsc.q=China%20COVID-19&gsc.page=1

首先,我需要获取页面的链接,所以我使用了这段代码:

def scrape(url):
    user_agent = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko'}
    request = 0
    params = {
        'q': 'China%20COVID-19',
        'gsc.tab': '0',
        'gsc.q': 'China%20COVID-19',
    }
    pagelinks = []
    
    myarticle = []
    for page_no in range(1,3):
        try:# to avoid "No connection adapters were found for" error
            params['gsc.page'] = page_no
            response = requests.get(url=url,
                                    headers=user_agent,
                                    params=params) 
            print(response.request.url)
            
        except Exception as e:
            print(e)
scrape('https://www.usnews.com/search/')

但是,结果不正确:

https://www.usnews.com/search?q=China%252520COVID-19&gsc.tab=0&gsc.q=China%252520COVID-19&gsc.page=1
https://www.usnews.com/search?q=China%252520COVID-19&gsc.tab=0&gsc.q=China%252520COVID-19&gsc.page=2

预期的结果应该是这样的:

https://www.usnews.com/search?q=China%20COVID-19#gsc.tab=0&gsc.q=China%20COVID-19&gsc.page=1
https://www.usnews.com/search?q=China%20COVID-19#gsc.tab=0&gsc.q=China%20COVID-19&gsc.page=2

有人可以帮我解决这个错误吗?非常感谢!

【问题讨论】:

  • 我对@9​​87654326@一无所知,但您的参数是否应该未编码:'q': 'China COVID-19' 即实际空间而不是编码为%20 的空间?

标签: python web-scraping beautifulsoup parameters request


【解决方案1】:

如果您在浏览器中打开您获得的 URL,您会看到搜索字符串是 China%2520COVID-19,而不是您所期望的 China COVID-19

您在查询字符串中看到的%20 是一个urlencoded 空格字符。见percent-encoding on MDN。如果你urldecodeChina%2520COVID-19,你会得到China%20COVID-19,由此我知道%25是编码的百分比字符。

可能requests 已经urlencodes 你的查询字符串值,所以你不需要。你可以改变它的工作是使用解码的值,例如空格 () 而不是 %20

    params = {
        'q': 'China COVID-19',
        'gsc.tab': '0',
        'gsc.q': 'China COVID-19',
    }

【讨论】:

  • 此代码不会导致预期的结果。将 URL 复制到浏览器中始终显示第一页。
【解决方案2】:

在浏览器中搜索“散列”网址 (https://www.usnews.com/search#...),您需要自己构建网址。
通过 requests.get(..., params=params) 将参数传递给请求会创建一个常规查询字符串 (https://www.usnews.com/search?...),该字符串会导致错误页面(始终是第一个)。

import requests
from urllib.parse import urlencode, unquote

def scrape(url):
    user_agent = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko'}
    request = 0
    url = 'https://www.usnews.com/search'
    params = {
        'q': 'China COVID-19',
        'gsc.tab': '0',
        'gsc.q': 'China COVID-19'
    }
    pagelinks = []
    myarticle = []

    for page_no in range(1,4):
        params['gsc.page'] = page_no
        _url = '%s#%s' % (url, urlencode(params))

        try:# to avoid "No connection adapters were found for" error
            response = requests.get(url=_url,
                                    headers=user_agent)
            print(_url, '>>', _url == unquote(response.request.url))

        except Exception as e:
            print(e)

scrape('https://www.usnews.com/search/')

输出:

https://www.usnews.com/search#q=China+COVID-19&gsc.tab=0&gsc.q=China+COVID-19&gsc.page=1 >> True
https://www.usnews.com/search#q=China+COVID-19&gsc.tab=0&gsc.q=China+COVID-19&gsc.page=2 >> True
https://www.usnews.com/search#q=China+COVID-19&gsc.tab=0&gsc.q=China+COVID-19&gsc.page=3 >> True

【讨论】:

  • 谢谢!但是最后一个答案对网址中的主题标签没有任何作用,它仍然返回正确的网址(没有#,但与#相同的页面)
  • @Yue Peng:我刚刚发布了这个,因为其他答案对我不起作用。将 URL 复制到浏览器中始终显示第一页。
  • 你是对的!感谢您的关注!我想知道你能解析你得到的网址吗?因为我需要从整体链接中抓取文章链接。
  • 类似:soup_page = bs(response, 'html.parser') #select all the articles for a single page: containers = soup_page.findAll("div", {'class': 'usn-site-search-item-container'}) #scrape the links of the articles: for i in containers: url = i.find('a') pagelinks.append(url.get('href')) print(pagelinks)
  • @Yue Peng:搜索结果是通过 Javascript 加载的,requests-library 无法做到这一点。即使在浏览器的源代码中也没有搜索结果(仅在 DOM 中)。
猜你喜欢
  • 2012-08-26
  • 2019-03-05
  • 1970-01-01
  • 2011-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-01
  • 2021-10-20
相关资源
最近更新 更多