日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

注意scrapy中SgmlLinkExtractor的默认deny_extensions

發布時間:2025/5/22 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 注意scrapy中SgmlLinkExtractor的默认deny_extensions 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在使用scrapy做爬蟲的時候碰到一個問題,耗了挺長時間都沒有解決,關鍵是從日志里面沒有看出問題,最后還是通過閱讀源碼才找出問題所在。在此將問題現象以及解決方法記錄一下。
現象:
  在一個頁面中有n多的連接,url的正則表達式如下:r"en/descriptions/[\d]+/[-:\.\w]+$",大部分連接都能抓取下來,但部分如 en/descriptions/32725456/not-a-virus:Client-SMTP.Win32.Blat.ai, en/descriptions/33444568/not-a-virus:Client-SMTP.Win32.Blat.au的卻抓取不到,日志中沒有任何提示信息。
分析:
  首先是懷疑CrawlSpider的Rule定義有問題,但經過測試發現Rule的定義正常;此時只能懷疑是SgmlLinkExtractor的定義的問題了,通過SgmlLinkExtractor的process_value的回調跟蹤來看,SgmlLinkExtractor在解析link的時候沒有問題,但最終返回時卻將部分link丟棄。
  通過源碼發現,scrapy.contrib.linkextractors.sgml.SgmlLinkExtractor在默認情況下將deny_extensions 設置為scrapy.linkextractor.IGNORED_EXTENSIONS,SgmlLinkExtractor在extract_links的時候調用_process_links, _process_links又調用了_link_allowed,在_link_allowed中依據種種過則對所有的link進行過濾,過濾規則中就有deny_extensions。默認IGNORED_EXTENSIONS將ai,au都包含了。所以也就出現了ai,au為結尾的link被過濾。至此真正的問題出處算是找到了。
解決方式:
  根據源碼分析的結果,在定義SgmlLinkExtractor時重新定義deny_extensions即可。比如

rules = (Rule(SgmlLinkExtractor(allow=(r"en/descriptions\?", )), follow = True, ),Rule(SgmlLinkExtractor(allow=(r"en/descriptions/[\d]+/[-:\.\w]+$", ), deny_extensions = ""), callback = "parse_item", follow = True),)

scrapy部分相關源碼如下:
scrapy.contrib.linkextractors.sgml.SgmlLinkExtractor:

class SgmlLinkExtractor(BaseSgmlLinkExtractor):def __init__(self, allow=(), deny=(), allow_domains=(), deny_domains=(), restrict_xpaths=(), tags=('a', 'area'), attrs=('href'), canonicalize=True, unique=True, process_value=None,deny_extensions=None):self.allow_res = [x if isinstance(x, _re_type) else re.compile(x) for x in arg_to_iter(allow)]self.deny_res = [x if isinstance(x, _re_type) else re.compile(x) for x in arg_to_iter(deny)]self.allow_domains = set(arg_to_iter(allow_domains))self.deny_domains = set(arg_to_iter(deny_domains))self.restrict_xpaths = tuple(arg_to_iter(restrict_xpaths))self.canonicalize = canonicalizeif deny_extensions is None:deny_extensions = IGNORED_EXTENSIONSself.deny_extensions = set(['.' + e for e in deny_extensions])tag_func = lambda x: x in tagsattr_func = lambda x: x in attrsBaseSgmlLinkExtractor.__init__(self, tag=tag_func, attr=attr_func, unique=unique, process_value=process_value)def extract_links(self, response):base_url = Noneif self.restrict_xpaths:hxs = HtmlXPathSelector(response)html = ''.join(''.join(html_fragm for html_fragm in hxs.select(xpath_expr).extract()) \for xpath_expr in self.restrict_xpaths)base_url = get_base_url(response)else:html = response.bodylinks = self._extract_links(html, response.url, response.encoding, base_url)links = self._process_links(links)return linksdef _process_links(self, links):links = [x for x in links if self._link_allowed(x)]links = BaseSgmlLinkExtractor._process_links(self, links)return linksdef _link_allowed(self, link):parsed_url = urlparse(link.url)allowed = _is_valid_url(link.url)if self.allow_res:allowed &= _matches(link.url, self.allow_res)if self.deny_res:allowed &= not _matches(link.url, self.deny_res)if self.allow_domains:allowed &= url_is_from_any_domain(parsed_url, self.allow_domains)if self.deny_domains:allowed &= not url_is_from_any_domain(parsed_url, self.deny_domains)if self.deny_extensions:allowed &= not url_has_any_extension(parsed_url, self.deny_extensions)if allowed and self.canonicalize:link.url = canonicalize_url(parsed_url)return alloweddef matches(self, url):if self.allow_domains and not url_is_from_any_domain(url, self.allow_domains):return Falseif self.deny_domains and url_is_from_any_domain(url, self.deny_domains):return Falseallowed = [regex.search(url) for regex in self.allow_res] if self.allow_res else [True]denied = [regex.search(url) for regex in self.deny_res] if self.deny_res else []return any(allowed) and not any(denied)

scrapy.linkextractor.IGNORED_EXTENSIONS:

IGNORED_EXTENSIONS = [# images'mng', 'pct', 'bmp', 'gif', 'jpg', 'jpeg', 'png', 'pst', 'psp', 'tif','tiff', 'ai', 'drw', 'dxf', 'eps', 'ps', 'svg',# audio'mp3', 'wma', 'ogg', 'wav', 'ra', 'aac', 'mid', 'au', 'aiff',# video'3gp', 'asf', 'asx', 'avi', 'mov', 'mp4', 'mpg', 'qt', 'rm', 'swf', 'wmv','m4a',# office suites'xls', 'ppt', 'doc', 'docx', 'odt', 'ods', 'odg', 'odp',# other'css', 'pdf', 'doc', 'exe', 'bin', 'rss', 'zip', 'rar', ]

轉載于:https://www.cnblogs.com/Jerryshome/archive/2012/10/23/2735129.html

總結

以上是生活随笔為你收集整理的注意scrapy中SgmlLinkExtractor的默认deny_extensions的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。