如何从网址中删除查询?

时间:2011-12-19 20:31:49

标签: python url scrapy web-crawler

我正在使用scrapy来抓取一个网站,该网站似乎在每个网址末尾的查询字符串中附加了随机值。这使得爬行成为一种无限循环。

如何让scrapy忽略URL的查询字符串部分?

6 个答案:

答案 0 :(得分:22)

请参阅urllib.urlparse

示例代码:

from urlparse import urlparse
o = urlparse('http://url.something.com/bla.html?querystring=stuff')

url_without_query_string = o.scheme + "://" + o.netloc + o.path

示例输出:

Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49) 
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from urlparse import urlparse
>>> o = urlparse('http://url.something.com/bla.html?querystring=stuff')
>>> url_without_query_string = o.scheme + "://" + o.netloc + o.path
>>> print url_without_query_string
http://url.something.com/bla.html
>>> 

答案 1 :(得分:10)

url_query_cleaner模块中有一个函数w3lib.url(由scrapy本身使用)来清理URL,只保留允许的参数列表。

答案 2 :(得分:6)

提供一些代码,以便我们为您提供帮助。

如果您将CrawlSpiderRuleSgmlLinkExtractor一起使用,请为proccess_value构造函数的SgmlLinkExtractor参数提供自定义函数。

请参阅BaseSgmlLinkExtractor

的文档
def delete_random_garbage_from_url(url):
    cleaned_url = ... # process url somehow
    return cleaned_url

Rule(
    SgmlLinkExtractor(
         # ... your allow, deny parameters, etc
         process_value=delete_random_garbage_from_url,
    )
)

答案 3 :(得分:3)

您可以使用urllib.parse.urlsplit() function。结果是structured parse result,一个具有附加功能的命名元组。

使用namedtuple._replace()方法更改已解析的结果值,然后使用SplitResult.geturl() method重新获取URL字符串。

要删除查询字符串,请将query的值设置为None

from urllib.parse import urlsplit

updated_url = urlsplit(url)._replace(query=None).geturl()

演示:

>>> from urllib.parse import urlsplit
>>> url = 'https://example.com/example/path?query_string=everything+after+the+questionmark'
>>> urlparse.urlsplit(url)._replace(query=None).geturl()
'https://example.com/example/path'

对于Python 2,urlparse.urlsplit() name下提供了相同的功能。

您也可以使用urllparse.parse.urlparse() function;对于没有任何path parameters的URL,结果将是相同的。这两个函数在处理路径参数的方式上有所不同。 urlparse()仅支持路径最后一段的路径参数,而urlsplit()将路径参数保留在路径中,从而将此类参数解析为其他代码。由于最近很少使用路径参数(后来的URL RFC完全删除了此功能),所以区别是学术上的。 urlparse()使用urlsplit()并且没有参数,除了额外的开销外,没有添加任何其他内容。最好直接使用urlsplit()

答案 4 :(得分:1)

使用此方法从url中删除查询字符串

urllink="http://url.something.com/bla.html?querystring=stuff"
url_final=urllink.split('?')[0]
print(url_final)

输出将是: http://url.something.com/bla.html

答案 5 :(得分:0)

如果您使用BaseSpider,在产生新请求之前,请使用urlparse从网址的查询部分手动删除随机值:

def parse(self, response):
    hxs = HtmlXPathSelector(response)
    item_urls = hxs.select(".//a[@class='...']/@href").extract()
    for item_url in item_urls:
        # remove the bad part of the query part of the URL here
        item_url = urlparse.urljoin(response.url, item_url)
        self.log('Found item URL: %s' % item_url)
        yield Request(item_url, callback = self.parse_item)