使用Scrapy创建包含特定关键词所有页面URL的JSON文件

0 投票
1 回答
930 浏览
提问于 2025-04-18 14:35

我正在使用scrapy解析多个网址/页面。在每个页面上,它会搜索特定的关键词,如果找到了,就把这个网址添加到一个叫Attribute_Dictionary的字典里。

每解析一个网址,Attribute_Dictionary就会更新一次。现在我想在解析完所有网址后,只写一次这个Attribute_Dictionary的内容到一个json文件里。

目前我写的代码是把内容写入json文件,但它在一次运行中会不断创建新的json文件,覆盖掉上一个文件。
我希望的结果是有一个包含所有网址的json文件,里面是Attribute_Dictionary的内容。

请帮帮我。我是不是应该创建一个全局变量来处理所有解析过的页面?如果是的话,应该怎么做呢?

def parse(self, response):
    global parsed_urls
    global domain_urls
    global tld
    global sliced_url
    items = []
    global item



    if ('html' not in response.headers['Content-Type']):
        return

    sel = Selector(response)


    for h3 in sel.xpath('//title/text()').extract():
         #print h3 + "***********" + ' <' + response.url + '>'
         sliced_url = response.url.split('/')[2]


    for url in sel.xpath('//a/@href').extract():

        if (url.startswith('/')):

            url = 'http://' + sliced_url + url



        if (url in parsed_urls or len(url) > 250):
            continue

        parsed_urls.append(url)

        if tld in url:
            domain_urls.append(url)
            yield Request(url, callback=self.parse)

        #print parsed_urls
        for keyword in Keyword_Dictionary:

            if (url.startswith('http') and (tld in url)):
                if (self.Search_keyword_in_url(keyword, response)):
                    if keyword not in Url_Dictionary:
                        Url_Dictionary[keyword] = []
                    Url_Dictionary[keyword].append(url)
                    #print keyword + " " + "Detected"



        for keyword in Url_Dictionary:

            Attribute_Key = []
            Attribute_Key = Keyword_Dictionary.get(keyword)
            Attribute_Key_Value = Url_Dictionary.get(keyword)
            for key in Attribute_Key:
                if key not in Attribute_Dictionary:
                    Attribute_Dictionary[key] = []
                    print key
                    print "\n"
                    for value in Attribute_Key_Value:
                        if value not in Attribute_Dictionary.get(key):
                            Attribute_Dictionary[key].append(value)
                            print key + " " + "Just Appended"
                            item = Website()
                            Modified_Key = key.replace(" ","_")
                            item[Modified_Key] = response.url
                            print item[Modified_Key]

        print Attribute_Dictionary
        # Json Code
        fileptr = open('keywords_spider.json','a')
        json.dump(Attribute_Dictionary, fileptr, indent=4)
        print "Created keywords_spiders.json.."
        fileptr.close()




def Search_keyword_in_url(self, keyword, response):

    sel = Selector(response)

    text_list = sel.xpath('//div/p/text()').extract()
    for text in text_list:
        if text.find(keyword) > -1:
            return True
    return False

1 个回答

2

我觉得你想做的事情有点复杂。可以考虑使用Item来简化一下。你可以在这里查看相关文档。另外,自己写文件并不是最好的方法。使用Items可以让Scrapy帮你处理输出,这样你可以轻松更改输出格式,或者通过Item Pipeline扩展功能。

如果你决定使用它们,我会给你一个解决方案。在你的项目中,创建一个名为items.py的文件,放在和spiders目录同一级别。

#items.py

from scrapy.item import Item, Field

class myFunkyUrlItem(Item):
    url = Field()
    keyword = Field()

现在在你的爬虫中,使用已有的逻辑来查找元素。当你找到这些元素时,创建一个myFunkyUrlItem

**#The Crawler!**
#import our custom item
from myProjectName.items import myFunkyUrlItem

def parse(self,response):
######Your existing scraper####
...
...
...

#When found
url_item = myFunkyUrlItem()    
url_item['url'] = response.url
url_item['keyword'] = the_keyword_found #Change this

#Give item to scrapy to process 
return url_item

最后,当你运行爬虫时,告诉Scrapy把找到的所有项目以json格式输出。

scrapy crawl myFunkySpider -o items.json

现在,

import json

my_items = json.load(open('items.json'))

print my_items[0]['url']
print my_items[0]['keyword']

希望这些对你有帮助。我还是不太确定我是否理解了你的问题。如果这不是你想要的,欢迎留言!

撰写回答