本文主要包含爬虫框架六大基础模块,分别为爬虫调度器、URL下载器、URL管理器、HTML下载器、HTML解析器、数据存储器
功能分析如下
- 爬虫调度器:主要负责统筹其他四个模块的工作。
- URL下载器:主要负责下载需要爬取数据的URL链接。
- URL管理器:负责管理URL链接,维护已经爬取的URL集合和未爬取的URL集合,提供获取新URL链接的接口。
- HTML下载器:用于从URL管理器中获取未爬取的URL链接并下载HRML网页。
- HTML解析器:用户从HTML下载器中获取已经下载的HTML网页,解析出有效数据交给数据存储器。
- 数据存储器:用于将HTML解析器解析出来的数据通过文件或者数据库的形式储存起来。
- 为了方便理解,以下是基础爬虫框架运行流程示意图
[外链图片转存失败(img-Gm7dSvnn-1566201386701)(https://upload-images.jianshu.io/upload_images/13406307-0c0e1059769c587d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
一、URL下载器
URL下载器包含两步,首先下载网站左侧导航栏的URL,然后通过导航栏的URL获取每个子栏目包含的链接列表。
[外链图片转存失败(img-haV3aHAw-1566201386701)(https://upload-images.jianshu.io/upload_images/13406307-35f58d52456b03c9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
下面是获取左侧导航栏所有链接并生成导航文件的代码
# -*- coding: utf-8 -*-
import pandas as pd
import urllib.request
from bs4 import BeautifulSoup
import re
import os
'''
遇到不懂的问题?Python学习交流群:821460695满足你的需求,资料都已经上传群文件,可以自行下载!
'''
class get_catalog(object):
'''生成和操作导航文件'''
def save_catalog(self):
'''获得证券之星左侧自导航的内容和网址并保存'''
#获取网页内容
url = 'http://quote.stockstar.com'
request =urllib.request.Request(url = url)
response = urllib.request.urlopen(request)
content = response.read().decode('gbk')
#截取左侧导航内容
soup = BeautifulSoup(content,"lxml")
soup = BeautifulSoup(str(soup.find_all('div',class_ = "subMenuBox")),"lxml")
#初始化一级子目录和二级子目录的数据框
catalog1 = pd.DataFrame(columns = ["cata1","cata2","url2"])
catalog2 = pd.DataFrame(columns = ["url2","cata3","url3"])
#整理目录内容和其对应的链接
index1 = 0;index2 = 0
for content1 in soup.find_all('div',class_ = re.compile("list submenu?")):
cata1 = re.findall('>(.*?)(.*?)(.*?) 0:
data = parser.get_dataframe()
# 数据储存器储存文件
out = DataOutput(self.engine,data,self.table_name)
out.output()
print('%s 的数据已存入表 %s'%(url,self.table_name))
time.sleep(1)
return(parser.get_datatime())
def crawl(self,urls):
'''爬取一个栏目连接列表的内容'''
self.manager.add_new_urls(urls)
# 判断url管理器中是否有新的url
pool = threadpool.ThreadPool(10)
while(self.manager.has_new_url()):
# 从URL管理器获取新的url
new_url = self.manager.get_new_url()
requests = threadpool.makeRequests(self.spider,(new_url,))
pool.putRequest(requests[0])
pool.wait()
完整代码
from firstSpider.get_proxy_ip import proxy_ip
from firstSpider.get_catalog import get_catalog
from firstSpider.get_urls import get_urls
from firstSpider.SpiderMan import SpiderMan
from selenium import webdriver
from sqlalchemy import create_engine
import time
'''
遇到不懂的问题?Python学习交流群:821460695满足你的需求,资料都已经上传群文件,可以自行下载!
'''
'''根据左侧子导航下载证券之星当天所有数据'''
if __name__ == "__main__":
print('获取代理IP并验证有效性')
ip_pool = proxy_ip('http://quote.stockstar.com',8)
ip_pool.get_ip()
print('代理IP池建立完毕')
getcata = get_catalog()
catalog = getcata.load_catalog()
start = 0
end = len(catalog)
catalog = catalog[start : end]
print('初始化浏览器')
browser = webdriver.Chrome()
engine = create_engine('mysql+pymysql://root:Jwd116875@localhost:3306/scott?charset=utf8')
for index in range(start,end):
table_name,url = getcata.index_info(catalog,index)
stop_url = ['http://quote.stockstar.com/gold/globalcurrency.shtml'] #想过滤掉的网页链接
if url not in stop_url:
geturls = get_urls(browser,url)
urls = geturls.get_urllist()
print('已获取 %s 的链接列表'%table_name)
Spider_man = SpiderMan(engine,table_name)
Spider_man.crawl(urls)
datatime = Spider_man.spider(urls[0])
print('%s: %s 栏目 %s 的增量数据爬取完毕'%(index,table_name,datatime))