Python 限制scrapy爬虫上的页面深度

Python 限制scrapy爬虫上的页面深度,python,scrapy,python-requests,jupyter-notebook,Python,Scrapy,Python Requests,Jupyter Notebook,我有一个scraper,它接收一个URL列表,扫描它们以寻找其他链接,然后使用REGEX查找任何看起来像电子邮件的内容,并返回一个URL/电子邮件地址列表 我目前在Jupyter笔记本中设置了它,因此我可以在测试时轻松查看输出。问题是,它需要永远运行——因为我没有限制每个URL的刮板深度 理想情况下,scraper将从每个起始url最多深入2-5页 以下是我目前掌握的情况: 首先,我要导入我的依赖项: import os, re, csv, scrapy, logging import pand

我有一个scraper,它接收一个URL列表,扫描它们以寻找其他链接,然后使用REGEX查找任何看起来像电子邮件的内容,并返回一个URL/电子邮件地址列表

我目前在Jupyter笔记本中设置了它,因此我可以在测试时轻松查看输出。问题是,它需要永远运行——因为我没有限制每个URL的刮板深度

理想情况下,scraper将从每个起始url最多深入2-5页

以下是我目前掌握的情况:

首先,我要导入我的依赖项:

import os, re, csv, scrapy, logging
import pandas as pd
from scrapy.crawler import CrawlerProcess
from scrapy.linkextractors.lxmlhtml import LxmlLinkExtractor
from googlesearch import search
from time import sleep
from Urls import URL_List
我在Jupyter笔记本中设置了关闭日志和使用Scrapy的警告:

logging.getLogger('scrapy').propagate = False
从那里,我从URL文件中提取URL:

def get_urls():
    urls = URL_List['urls']
然后,我设置了我的蜘蛛:

class MailSpider(scrapy.Spider):
    name = 'email'
    def parse(self, response):
我在URL中搜索链接

        links = LxmlLinkExtractor(allow=()).extract_links(response)
然后将URL列表作为输入,逐个读取其源代码

        links = [str(link.url) for link in links]
        links.append(str(response.url))
我将链接从一个解析方法发送到另一个解析方法。 并设置回调参数,该参数定义请求URL必须发送到的方法

        for link in links:
            yield scrapy.Request(url=link, callback=self.parse_link)        
然后我将URL传递给parse_link方法 — 此方法应用regex findall查找电子邮件

    def parse_link(self, response):
        html_text = str(response.text)
        mail_list = re.findall('\w+@\w+\.{1}\w+', html_text)
        dic = {'email': mail_list, 'link': str(response.url)}
        df = pd.DataFrame(dic)
        df.to_csv(self.path, mode='a', header=False)
当我们调用process方法来运行Spider时,google_url列表作为参数传递,path定义了保存CSV文件的位置

然后,我将这些电子邮件保存在CSV文件中:

def ask_user(question):
    response = input(question + ' y/n' + '\n')
    if response == 'y':
        return True
    else:
        return False

def create_file(path):
    response = False
    if os.path.exists(path):
        response = ask_user('File already exists, replace?')
        if response == False: return 
    with open(path, 'wb') as file: 
        file.close()
对于每个网站,我都会创建一个包含列:[电子邮件,链接]的数据框,并将其附加到以前创建的CSV文件中

然后,我把它们放在一起:

def get_info(root_file, path):  
    create_file(path)
    df = pd.DataFrame(columns=['email', 'link'], index=[0])
    df.to_csv(path, mode='w', header=True)

    print('Collecting urls...')
    google_urls = get_urls()

    print('Searching for emails...')
    process = CrawlerProcess({'USER_AGENT': 'Mozilla/5.0'})
    process.crawl(MailSpider, start_urls=google_urls, path=path)

    process.start()

    print('Cleaning emails...')
    df = pd.read_csv(path, index_col=0)
    df.columns = ['email', 'link']
    df = df.drop_duplicates(subset='email')
    df = df.reset_index(drop=True)
    df.to_csv(path, mode='w', header=True)

    return df

get_urls()
最后,我定义一个关键字并运行scraper:

keyword = input("Who is the client? ")
df = get_info(f'{keyword}_urls.py', f'{keyword}_emails.csv')
在100个URL的列表中,我得到了44k个带有电子邮件地址语法的结果


有人知道如何限制深度吗?

像这样在你的蜘蛛身上设置深度限制

class MailSpider(scrapy.Spider):
    name = 'email'

    custom_settings = {
        "DEPTH_LIMIT": 5
    }

    def parse(self, response):
        pass

可以使用默认启用的DepthLimitMiddleware设置深度限制。有关其设置,请参见:有趣。谢谢你知道如何在文件@PhungDuyPhong中运行它吗?