我在试着刮github repo。
我想在每个repo的level1中提取所有XML文件URL,并且在最好的情况下也从XML文件中提取信息。
import scrapy
from scrapy.crawler import CrawlerProcess
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
repo_rule = Rule(
LinkExtractor(
restrict_xpaths="//a[@itemprop='name codeRepository']",
restrict_text=r"ELTeC-.+"
)
)
pagination_rule = Rule(
LinkExtractor(restrict_xpaths="//a[@class='next_page']")
)
level_rule = Rule(
LinkExtractor(allow=r"/level1"),
follow=True,
callback="parse_level"
)
class ELTecSpider(CrawlSpider):
"""Scrapy CrawlSpider for crawling the ELTec repo."""
name = "eltec"
start_urls = ["https://github.com/orgs/COST-ELTeC/repositories"]
rules = [
repo_rule,
pagination_rule,
level_rule,
]
def parse_level(self, response):
print("INFO: ", response.url)
process = CrawlerProcess(
settings={
"FEEDS": {
"items.json": {
"format": "json",
"overwrite": True
},
},
}
)
process.crawl(ELTecSpider)
process.start()
字符串
上面提取了所有level1文件夹的响应,但不知何故,我在这一点上卡住了。我的计划是使用回调函数来访问每个level1 URL,如下所示:
def parse_level(self, response):
yield scrapy.Request(response.url, callback=self.parse_docs)
def parse_docs(self, response):
docs_urls = response.xpath("//a[@class='Link--primary']")
for url in docs_urls:
print("INFO: ", url)
型
但很明显回调函数从来没有触发过。
我做错了什么?
1条答案
按热度按时间rwqw0loc1#
scrapy
记住访问过的页面,并跳过再次抓取相同的url
。这样就不会浪费时间再次获取相同的页面,而且还可以防止爬行循环。
当你运行
scrapy.Request(response.url, ...)
时,你试图再次抓取相同的url
,scrapy
跳过了它。如果你真的需要刮同一页再次那么你可能需要
字符串
(Doc:scrapy.http.Request)
我宁愿直接跑
型
parse_doc()
内部还有一个问题。xpath
找不到任何元素-所以for
-loop不会运行任何print()
。您应该在parse_doc()
的开头添加额外的print()
以查看它是何时执行的。xpath
可能找不到class='Link--primary'
,因为此页面使用JavaScript
添加元素。这可能需要使用Selenium和模块scrapy-selenium
来控制可以运行JavaScript
的真实的Web浏览器。scrapy
也有Splash和scrapy-splash与JavaScript
一起工作。(Doc:Selecting dynamically-loaded content)
也许
GitHub
有一些API可以在不刮取的情况下获取信息。编辑:
完整的工作代码,使用
scrapy-selenium
和Selenium 3
。它不适用于
Selenium 4
,因为scrapy-selenium
自2020年以来没有更新,并且它不适用于最新的Selenium 4
的字符串
来源:
items.json
型