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