【发布时间】:2012-01-23 22:16:20
【问题描述】:
我正在使用 scrapy 来抓取一个网站,该网站似乎在每个 URL 末尾的查询字符串中附加了随机值。这将爬行变成了一种无限循环。
如何让 scrapy 忽略 URL 的查询字符串部分?
【问题讨论】:
标签: python url scrapy web-crawler
我正在使用 scrapy 来抓取一个网站,该网站似乎在每个 URL 末尾的查询字符串中附加了随机值。这将爬行变成了一种无限循环。
如何让 scrapy 忽略 URL 的查询字符串部分?
【问题讨论】:
标签: python url scrapy web-crawler
提供一些代码,以便我们为您提供帮助。
如果您将CrawlSpider 和Rule 与SgmlLinkExtractor 一起使用,请为SgmlLinkExtractor 构造函数的proccess_value 参数提供自定义函数。
请参阅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,
)
)
【讨论】:
如果您使用 BaseSpider,在产生新请求之前,请使用 urlparse 从 URL 的查询部分手动删除随机值:
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)
【讨论】:
示例代码:
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
>>>
【讨论】:
from urllib.parse import urlparse ?
from urllib.parse import urlparse 为我工作。
o._replace(query=None).geturl()
w3lib.url 模块中有一个函数 url_query_cleaner(由 scrapy 自己使用)来清理 url,只保留允许的参数列表。
【讨论】:
您可以使用urllib.parse.urlsplit() function。结果是一个structured parse result,一个具有附加功能的命名元组。
使用namedtuple._replace() 方法更改解析结果值,然后使用SplitResult.geturl() method 再次获取URL 字符串。
要删除查询字符串,请将@987654330@ 值设置为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()。
【讨论】:
使用此方法从 url 中删除查询字符串
urllink="http://url.something.com/bla.html?querystring=stuff"
url_final=urllink.split('?')[0]
print(url_final)
【讨论】: