【发布时间】:2021-12-11 15:19:14
【问题描述】:
情况:
我最近开始使用 selenium 和 scrapy 进行网络抓取,我正在做一个项目,我有一个包含 42000 个邮政编码的 csv 文件,我的工作是获取该邮政编码并继续 site 输入邮政编码编码并抓取所有结果。
问题:
这里的问题是,在执行此操作时,我必须不断单击“加载更多”按钮,直到显示所有结果,并且只有在完成后我才能收集数据。
这可能不是什么大问题,但是每个邮政编码需要 2 分钟,而我有 42000 人可以这样做。
守则:
import scrapy
from numpy.lib.npyio import load
from selenium import webdriver
from selenium.common.exceptions import ElementClickInterceptedException, ElementNotInteractableException, ElementNotSelectableException, NoSuchElementException, StaleElementReferenceException
from selenium.webdriver.common.keys import Keys
from items import CareCreditItem
from datetime import datetime
import os
from scrapy.crawler import CrawlerProcess
global pin_code
pin_code = input("enter pin code")
class CareCredit1Spider(scrapy.Spider):
name = 'care_credit_1'
start_urls = ['https://www.carecredit.com/doctor-locator/results/Any-Profession/Any-Specialty//?Sort=D&Radius=75&Page=1']
def start_requests(self):
directory = os.getcwd()
options = webdriver.ChromeOptions()
options.headless = True
options.add_experimental_option("excludeSwitches", ["enable-logging"])
path = (directory+r"\\Chromedriver.exe")
driver = webdriver.Chrome(path,options=options)
#URL of the website
url = "https://www.carecredit.com/doctor-locator/results/Any-Profession/Any-Specialty/" +pin_code + "/?Sort=D&Radius=75&Page=1"
driver.maximize_window()
#opening link in the browser
driver.get(url)
driver.implicitly_wait(200)
try:
cookies = driver.find_element_by_xpath('//*[@id="onetrust-accept-btn-handler"]')
cookies.click()
except:
pass
i = 0
loadMoreButtonExists = True
while loadMoreButtonExists:
try:
load_more = driver.find_element_by_xpath('//*[@id="next-page"]')
load_more.click()
driver.implicitly_wait(30)
except ElementNotInteractableException:
loadMoreButtonExists = False
except ElementClickInterceptedException:
pass
except StaleElementReferenceException:
pass
except NoSuchElementException:
loadMoreButtonExists = False
try:
previous_page = driver.find_element_by_xpath('//*[@id="previous-page"]')
previous_page.click()
except:
pass
name = driver.find_elements_by_class_name('dl-result-item')
r = 1
temp_list=[]
j = 0
for element in name:
link = element.find_element_by_tag_name('a')
c = link.get_property('href')
yield scrapy.Request(c)
def parse(self, response):
item = CareCreditItem()
item['Practise_name'] = response.css('h1 ::text').get()
item['address'] = response.css('.google-maps-external ::text').get()
item['phone_no'] = response.css('.dl-detail-phone ::text').get()
yield item
now = datetime.now()
dt_string = now.strftime("%d/%m/%Y")
dt = now.strftime("%H-%M-%S")
file_name = dt_string+"_"+dt+"zip-code"+pin_code+".csv"
process = CrawlerProcess(settings={
'FEED_URI' : file_name,
'FEED_FORMAT':'csv'
})
process.crawl(CareCredit1Spider)
process.start()
print("CSV File is Ready")
items.py
import scrapy
class CareCreditItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
Practise_name = scrapy.Field()
address = scrapy.Field()
phone_no = scrapy.Field()
问题:
基本上我的问题很简单。有没有办法优化此代码以使其执行得更快?或者还有哪些其他潜在的方法可以处理抓取这些数据而无需花费太多时间?
【问题讨论】:
-
您是否在使用任何其他外部资源?因为您可以使用例如来自 aws 的 ec2 实例将种子列表分布在这些实例上,甚至可能发现实例以并行运行刮板,同时刮取许多邮政编码
-
感谢您回复@Kwsswart,但我不太明白您在说什么,您能稍微解释一下或给我一些参考链接以了解/
-
基本上如果你将邮政编码(种子列表)分成许多单独的种子列表并开发一个解决方案来运行相同的蜘蛛,但在许多不同的机器上使用不同的种子列表(aws instances 是一个例子)那么你可以本质上,有许多机器同时使用原始种子列表的不同部分进行处理
-
哦,是的,这是解决这个问题的好方法,非常感谢您的帮助,还有其他方法可以像不部署一样进行大规模抓取吗?
-
有很多大规模的方法,特别是在 AWS 中使用 Lambda 或 ec2 等。但是如果你只想使用一台机器,你可以研究多线程(使用所述 pc 中的所有处理器同时运行程序。)或者考虑在单个进程上连续(尽管缓慢)运行它。您也可以尝试简单地使用请求来运行它,这可能会加快速度,但使用大量种子通常会更快地开发并行运行的进程
标签: python selenium web-scraping scrapy