环境搭建
安装
安装python爬虫框架scrapy
$ pip install scrapy
由于页面是动态渲染的,所以采用打开浏览器的方式进行数据爬取,所以需要安装selenium
$ pip install selenium
脚手架搭建
- 创建项目命令:
scrapy startproject “项目名”
- 创建爬虫文件命令:
scrapy genspider “爬虫名” “爬虫范围”
- 启动一个爬虫:
scrapy crawl “爬虫名字”
$ scrapy startproject wyspider
$ scrapy genspider home guahao.com
$ scrapy crawl home
scrapy框架
- Scrapy Engine(引擎): 负责
Spider
、ItemPipeline
、Downloader
、Scheduler
中间的通讯,信号、数据传递等。 - Scheduler(调度器): 它负责接受引擎发送过来的Request请求,并按照一定的方式进行整理排列,入队,当引擎需要时,交还给引擎。
- Downloader(下载器):负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spider来处理,
- Spider(爬虫):它负责处理所有Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器),
- Item Pipeline(管道):它负责处理Spider中获取到的Item,并进行进行后期处理(详细分析、过滤、存储等)的地方.
- Downloader Middlewares(下载中间件):你可以当作是一个可以自定义扩展下载功能的组件。
- Spider Middlewares(Spider中间件):你可以理解为是一个可以自定扩展和操作引擎和Spider中间通信的功能组件(比如进入Spider的Responses;和从Spider出去的Requests)
scrapy框架流程
start_urls快速走了一遍流程再开始parse()
- 引擎拿到request请求发送给调度器整理入列
- 调度器返回request请求给引擎
- 引擎发送request请求给下载器
- 下载器前往互联网进行下载response返回给引擎
- 引擎把response返回给爬虫
- 爬虫返回items或者request给引擎
- items返回给管道,request进行下一轮循环
中间件
编写编写
这次的目标暂定为打开一个页面后截图进行保存,所以我们在中间件中操作截图
代码语言:javascript复制class ChromeSpiderMiddleware(object):
def save_screenshot(self, spider):
file_name = f'{spider.driver.title}_{int(time.time() * 1000)}.png'
spider.driver.save_screenshot(f'{LOG_PATH}/{file_name}')
logger.info(f'爬取的地址为:{spider.driver.current_url},页面名称为:{spider.driver.title},截图名称为:{file_name}')
def process_request(self, request, spider):
spider.driver.get(request.url)
time.sleep(0.5)
self.save_screenshot(spider)
html = spider.driver.page_source
return scrapy.http.HtmlResponse(url=request.url, body=html.encode('utf-8'), encoding='utf-8',
request=request)
开启中间件
在settings.py
中修改DOWNLOADER_MIDDLEWARES
DOWNLOADER_MIDDLEWARES = {
'wyspider.middlewares.ChromeSpiderMiddleware': 543,
}
编写爬虫
设置爬取范围与初始爬取地址
- 爬取范围:allowed_domains
- 初始爬取地址:base_url
class HomeSpider(scrapy.Spider):
name = 'home'
allowed_domains = ['guahao.com']
base_url = 'https://wy.guahao.com'
start_urls = [
base_url
]
打开浏览器
在最开始爬取的时候,需要先打开浏览器,建议采用无头浏览器
def __init__(self):
super(HomeSpider, self).__init__(name=self.name)
chrome_option = Options()
chrome_option.add_experimental_option('mobileEmulation', {'deviceName': 'iPhone X'})
chrome_option.add_experimental_option('w3c', False)
desired_capabilities = DesiredCapabilities.CHROME
desired_capabilities["pageLoadStrategy"] = "eager"
chrome_option.add_argument('--headless')
chrome_option.add_argument('--disable-gpu')
chrome_option.add_argument('--no-sandbox')
self.driver = webdriver.Chrome(executable_path=f'{TOOL_PATH}/chromedriver',
chrome_options=chrome_option,
desired_capabilities=desired_capabilities)
爬虫主体
找到页面上a标签
的链接
然后与基础url
进行拼接
打开新的页面后递归
调用爬虫函数
继续在新打开的页面中找到a标签地址
直到没有a标签或者超出运行爬取的域名外结束爬虫
代码语言:javascript复制def parse(self, response):
url_list = response.xpath('//a/@href').extract()
url_list = [i.strip() for i in url_list if 'javascript:' not in i]
logger.info(f'爬取的地址列表为:{url_list}')
for url in url_list:
if url.startswith("http"):
link = url
else:
link = self.base_url url
logger.info(f'爬取的地址为:{link}')
yield scrapy.Request(url=link, callback=self.parse)
执行日志
下面是最开始的第一条爬虫数据,打开了首页,然后再首页找到了n个链接,依次进入链接后进行截图,并重复开始的流程
代码语言:javascript复制2021-11-01 10:25:04,444-INFO-python:爬取的地址为:https://wy.guahao.com/,页面名称为:微医(挂号网)-互联网医院在线诊疗平台,截图名称为:微医(挂号网)-互联网医院在线诊疗平台_1635733502798.png
2021-11-01 10:25:09,005-INFO-python:爬取的地址列表为:['/home/search', 'https://hmall.guahao.com/activity/42d771de31734906b73a8437e0e124b7', 'https://vip.guahao.com', 'https://hd.guahao.com/u/29691?channelNumber=C0039N2489K', 'https://hd.guahao.com/u/28844?channelNumber=C0039N2489K', 'https://hd.guahao.com/u/29597?_channel=hdyx026a&huiyuanzhuanshu', 'https://hd.guahao.com/u/28963?_channel=hdyx005a', 'https://weex.guahao.com/weex/alias/portal/special-disease/more', 'https://app.wy.guahao.com/medical-examination?app_disable_navbar=1&frompage=home', 'https://hd.guahao.com/u/28160?cp=fjjwyapp', 'https://industry.guahao.com/as?source_id=51111', 'https://industry.guahao.com/activity/a5666e96aa7c4e4d9f34f09a25c79b58?source_id=40948&_cp=my713', 'https://hd.guahao.com/u/28475', 'https://wy.guahao.com/ums/cdm?diseaseCode=39816&_cp=tnbapp', 'https://hd.guahao.com/u/28822?gytx1=', 'https://industry-consume.guahao.com/activity/09f0fe82ab9f45928e6b78a5d17ad85c?trace=appzbzk', 'https://wy.guahao.com/home/tumor-hospital', 'https://www.wjx.cn/vj/tjAgy5b.aspx', 'https://doctorbridge.guahao.com/app/list', 'https://hmall.guahao.com/index', 'https://hmall.guahao.com/opt/item/492747083989835776', 'https://hmall.guahao.com/opt/item/541605568869101568', 'https://hmall.guahao.com/opt/item/528150867959934976', 'https://hmall.guahao.com/opt/item/492765816078655488', 'https://hmall.guahao.com/opt/item/515100617632444416', 'https://hmall.guahao.com/opt/item/497746177573322752', '/', '/consult/doctor', '/guide/disease', '/my/follow/expertlist', '/navigation', '/my/profile']
2021-11-01 10:25:09,006-INFO-python:爬取的地址为:https://wy.guahao.com/home/search
2021-11-01 10:25:10,285-INFO-python:爬取的地址为:https://wy.guahao.com/home/search,页面名称为:搜索,截图名称为:搜索_1635733510041.png
2021-11-01 10:25:12,468-INFO-python:爬取的地址为:https://wy.guahao.com/consult/portal,页面名称为:在线问诊,截图名称为:在线问诊_1635733512095.png
2021-11-01 10:25:12,500-INFO-python:爬取的地址为:https://hmall.guahao.com/activity/42d771de31734906b73a8437e0e124b7
2021-11-01 10:25:12,500-INFO-python:爬取的地址为:https://vip.guahao.com
2021-11-01 10:25:12,501-INFO-python:爬取的地址为:https://hd.guahao.com/u/29691?channelNumber=C0039N2489K
2021-11-01 10:25:12,501-INFO-python:爬取的地址为:https://hd.guahao.com/u/28844?channelNumber=C0039N2489K
2021-11-01 10:25:12,502-INFO-python:爬取的地址为:https://hd.guahao.com/u/29597?_channel=hdyx026a&huiyuanzhuanshu
2021-11-01 10:25:12,502-INFO-python:爬取的地址为:https://hd.guahao.com/u/28963?_channel=hdyx005a
2021-11-01 10:25:12,503-INFO-python:爬取的地址为:https://weex.guahao.com/weex/alias/portal/special-disease/more
2021-11-01 10:25:12,504-INFO-python:爬取的地址为:https://app.wy.guahao.com/medical-examination?app_disable_navbar=1&frompage=home
2021-11-01 10:25:12,504-INFO-python:爬取的地址为:https://hd.guahao.com/u/28160?cp=fjjwyapp
2021-11-01 10:25:12,505-INFO-python:爬取的地址为:https://industry.guahao.com/as?source_id=51111
2021-11-01 10:25:12,506-INFO-python:爬取的地址为:https://industry.guahao.com/activity/a5666e96aa7c4e4d9f34f09a25c79b58?source_id=40948&_cp=my713
2021-11-01 10:25:12,506-INFO-python:爬取的地址为:https://hd.guahao.com/u/28475
2021-11-01 10:25:12,507-INFO-python:爬取的地址为:https://wy.guahao.com/ums/cdm?diseaseCode=39816&_cp=tnbapp
2021-11-01 10:25:12,507-INFO-python:爬取的地址为:https://hd.guahao.com/u/28822?gytx1=
2021-11-01 10:25:12,508-INFO-python:爬取的地址为:https://industry-consume.guahao.com/activity/09f0fe82ab9f45928e6b78a5d17ad85c?trace=appzbzk
2021-11-01 10:25:12,509-INFO-python:爬取的地址为:https://wy.guahao.com/home/tumor-hospital
2021-11-01 10:25:12,509-INFO-python:爬取的地址为:https://www.wjx.cn/vj/tjAgy5b.aspx
2021-11-01 10:25:12,510-INFO-python:爬取的地址为:https://doctorbridge.guahao.com/app/list
截图