python爬虫示例,获取主页面链接,次级页面链接通过主页面元素获取从而避免js生成变动的值,保存数据分批次避免数据丢失

简介: python爬虫示例,获取主页面链接,次级页面链接通过主页面元素获取从而避免js生成变动的值,保存数据分批次避免数据丢失
# -*- coding: utf-8 -*-# import scrapyimportpandasaspdfrommathimportceilimportreimportrequestsimportrefrombs4importBeautifulSoupfromopenpyxlimportWorkbookfromopenpyxlimportload_workbook# from cve_details.items import CveDetailsItem# class CveDetailSpider(scrapy.Spider):#     name = 'cve_detail'#     allowed_domains = ['https://www.cvedetails.com']#     start_urls = [#         "https://www.cvedetails.com/vulnerability-list/year-" + str(i) + "/vulnerabilities.html" for i in range(1999, 2021)#     ]##     def get_url(self, page, year, trc):#         return "https://www.cvedetails.com/vulnerability-list.php?vendor_id=0&product_id=0&version_id=0&page={}&hasexp=0&opdos=0&opec=0&opov=0&opcsrf=0&opgpriv=0&opsqli=0&opxss=0&opdirt=0&opmemc=0&ophttprs=0&opbyp=0&opfileinc=0&opginf=0&cvssscoremin=0&cvssscoremax=0&year={}&month=0&cweid=0&order=1&trc={}&sha=ef7bb39664f094781e7b403da0e482830f5837d6".format \#             (page, year, trc)##     def parse(self, response):#         # 得到页数,生成url#         nums = response.selector.xpath('//div[@id="pagingb"]/b/text()').get()   # 获取cve的数量#         pages = ceil(int(nums ) /50)                                              # 算出页数#         for year in range(1999, 2021):#             for page in range(1, page s +1):#                 newurl = self.get_url(str(page), str(year), str(nums))#                 yield scrapy.Request(url=newurl, callback=self.parse1, dont_filter=True)##     def parse1(self, response):#         detailurls = response.selector.xpath \#             ('//div[@id="searchresults"]/table/tr[@class="srrowns"]/td[@nowrap]/a/@href').getall()#         for detailurl in detailurls:#             durl = "https://www.cvedetails.com" + detailurl#             yield scrapy.Request(url=durl, callback=self.parse2, dont_filter=True)##     def parse2(self, response):#         # CVE编号,危害等级,漏洞类型,供应商,型号,设备类型,固件版本号#         cveid = response.selector.xpath('//h1/a/text()').get()#         score = response.selector.xpath('//div[@class="cvssbox"]/text()').get()#         if score == '0.0':#             return None#         vulntype =  re.findall(r'">(.*?)</span>', response.selector.xpath('//table[@id="cvssscorestable"]/tr').getall()[-2])#         vulntype = '' if vulntype == [] else vulntype[0]#         makes = response.selector.xpath('//table[@id="vulnprodstable"]/tr').getall()[1:]#         rule1 = re.compile(r'<a .*>(.*)</a>')#         rule2 = re.compile(r'<td>\s+(.*?)\s+</td>')#         for make in makes:#             vendor ,product ,_ = rule1.findall(make)#             producttype ,_ ,_ ,version ,_ ,_ ,_ ,_ = rule2.findall(make)#             item = CveDetailsItem()#             item['cveid'] ,item['score'] ,item['vulntype'] ,item['vendor'] ,item['product'] ,item['producttype'] ,item#                 ['version'] = cveid ,score ,vulntype ,vendor ,product ,producttype ,version#             yield item#             # print(cveid,score,vulntype,vendor,product,producttype,version)classCveDetailSpider2():
result_num=0name='cve_detail'allowed_domains= ['https://www.cvedetails.com']
start_urls= [
"https://www.cvedetails.com/vulnerability-list/year-"+str(i) +"/vulnerabilities.html"foriinrange(1999,2000)
    ]
headers= {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)' \
' AppleWebKit/537.36 (KHTML, like Gecko)' \
' Chrome/58.0.3029.110 Safari/537.3'}
defget_url(self, page, year, trc):
return"https://www.cvedetails.com/vulnerability-list.php?vendor_id=0&product_id=0&version_id=0&page={}&hasexp=0&opdos=0&opec=0&opov=0&opcsrf=0&opgpriv=0&opsqli=0&opxss=0&opdirt=0&opmemc=0&ophttprs=0&opbyp=0&opfileinc=0&opginf=0&cvssscoremin=0&cvssscoremax=0&year={}&month=0&cweid=0&order=1&trc={}&sha=b87d72f681722fd5f26c1153b2202a4f05acfff1".format(
page, year, trc)
defparse(self,start_y=1999,end_y=2000):
foryearinrange(start_y, end_y+1):
response=requests.get("https://www.cvedetails.com/vulnerability-list/year-"+str(year) +"/vulnerabilities.html", headers=self.headers)
soup=BeautifulSoup(response.content, 'html.parser')
# 得到页数,生成urlrows=soup.find_all('div', {'id': 'pagingb'})
# nums=rows[0].find_all('b')# nums=nums[0].text# print(nums)# pages = ceil(int(nums) / 50)  # 算出页数# for page in range(1, pages + 1):#     newurl = self.get_url(str(page), str(year), str(nums))#     print(newurl)forrowinrows[0].find_all('a',href=True):
newurl="https://www.cvedetails.com"+row['href']
# print(newurl)tag=self.parse1(newurl,year)
iftag==0:
print('continue!---',year)
continueiftag==1:
print('break!---',year)
breakdefparse1(self, url,year):
response=requests.get(url, headers=self.headers)
# # 基于 BeautifulSoup 解析数据soup=BeautifulSoup(response.content, 'html.parser')
# # 获取所有的表格行rows=soup.find_all('tr', {'class': 'srrowns'})
self.result_num+=len(rows)
#跳过前面多少记录ifself.result_num<6000:
print("跳过 result_num:%d"%self.result_num)
return0#到多少条停止ifself.result_num>10000:
print("停止 result_num:%d"%self.result_num)
self.result_num=0return1print('self.result_num:',self.result_num)
forrowinrows:
durl="https://www.cvedetails.com"+row.find_all('a', href=True)[0]['href']
print(durl)
ifdurl.split('/')[-2].split('-')[1]!=str(year):
print('{0}年数据已完成!!跳到下一年'.format(year))
self.result_num=0return1ifdurlnotin ['https://www.cvedetails.com/cve/CVE-2010-4609/',
'https://www.cvedetails.com/cve/CVE-2010-2812/',
'https://www.cvedetails.com/cve/CVE-2014-0629/',
"https://www.cvedetails.com/cve/CVE-2017-14064/",
"https://www.cvedetails.com/cve/CVE-2017-11027/",
"https://www.cvedetails.com/cve/CVE-2017-8760/"                                ]:
self.parse2(durl)
# breakdefparse2(self, path2):
response=requests.get(path2, headers=self.headers)
soup=BeautifulSoup(response.content, 'html.parser')
rows=soup.find_all('h1')
cveid=""iflen(rows)>0:
print(rows[0].find_all('a', href=True)[0].text)
cveid=rows[0].find_all('a', href=True)[0].textifcveidinexist_cv1:
print('{0}已存在,跳过!!'.format(cveid))
returnrows=soup.find_all('div', {'class': 'cvedetailssummary'})
describe=''iflen(rows) >0:
describe_str=rows[0].textdescribe_str=describe_str.strip()
describe=describe_str.split('\t')[0]
# print(describe)score=''iflen(rows) >0:
rows=soup.find_all('div', {'class': 'cvssbox'})
iflen(rows) >0:
print(rows[0].text)
score=rows[0].textvulntype=""iflen(rows) >0:
rows=soup.find_all('span', {'class': 'vt_dos'})
iflen(rows) >0:
print(rows[0].text)
vulntype=rows[0].textproducttype= []
vendor= []
product= []
version= []
rows_table=soup.find_all('table', {'class': 'listtable', 'id': 'vulnprodstable'})
# try:iflen(rows_table) >0:
rows_tr=rows_table[0].find_all('tr')
tr_num=len(rows_tr)
iftr_num>1:
foriinrange(1,tr_num):
rows_td=rows_tr[i].find_all('td')
iflen(rows_td) >1:
# print(rows_td)producttype.append(rows_td[1].text.strip())
vendor.append(rows_td[2].text.strip())
product.append(rows_td[3].text.strip())
version.append(rows_td[4].text.strip())
# product = rows[1].text.strip()item= {}
item['cveid'],item['describe'], item['score'], item['vulntype'], item['producttype'], item['vendor'], item['product'], item[
'version'] =cveid, describe,score, vulntype, "|".join(set(producttype)), "|".join(set(vendor)), "|".join(set(product)), "|".join(set(version))
print(item)
filename='output(2015).xlsx'try:
workbook=load_workbook(filename)
worksheet=workbook.activeexceptFileNotFoundError:
workbook=Workbook()
worksheet=workbook.activeheader= ['cveid', 'describe','score', 'vulntype', 'producttype', 'vendor', 'product', 'version']
worksheet.append(header)
finally:
values= [item['cveid'],item['describe'], item['score'], item['vulntype'], item['producttype'], item['vendor'], item['product'], item[
'version']]
worksheet.append(values)
workbook.save(filename)
workbook.close()
defget_cve_data(start_page: int, num_records: int) ->None:
# 设置 url 和 headersurl=f'https://www.cvedetails.com/vulnerability-list.php?' \
f'vendor_id=0&product_id=0&version_id=0&page={start_page}' \
f'&numrows={num_records}&hasexp=0&opdos=0&opec=0&opov=0' \
f'&opcsrf=0&opgpriv=0&opsqli=0&opxss=0&opdirt=0&opmemc=0' \
f'&ophttprs=0&opbyp=0&opfileinc=0&opginf=0&cvssscoremin=0' \
f'&cvssscoremax=0&year=0&month=0&cweid=0&order=1&trc=0&sha=' \
f'8a181058fa3202146b2bbf6c9a982505c6d25cc3'headers= {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)' \
' AppleWebKit/537.36 (KHTML, like Gecko)' \
' Chrome/58.0.3029.110 Safari/537.3'}
# 发送网络请求response=requests.get(url, headers=headers)
# # 基于 BeautifulSoup 解析数据soup=BeautifulSoup(response.content, 'html.parser')
# # 获取所有的表格行rows=soup.find_all('tr', {'class': 'srrowns'})
forrowinrows:
# print('-------------------')# print(row.find_all('a',href=True)[0])# print(row.find_all('a', href=True)[0]['href'])# print(row.find_all('a',href=True)[0].text)path2=row.find_all('a', href=True)[0]['href']
# for detailurl in detailurls:path2="https://www.cvedetails.com"+path2path2='https://www.cvedetails.com/cve/CVE-1999-1567/'print(path2)
response=requests.get(path2, headers=headers)
soup=BeautifulSoup(response.content, 'html.parser')
rows=soup.find_all('h1')
print(rows[0].find_all('a',href=True)[0].text)
cveid=rows[0].find_all('a',href=True)[0].textrows=soup.find_all('div',{'class': 'cvssbox'})
print(rows[0].text)
score=rows[0].textrows=soup.find_all('span', {'class': 'vt_dos'})
print(rows[0].text)
vulntype=rows[0].textrows=soup.find_all('table', {'class': 'listtable','id':'vulnprodstable'})
rows=rows[0].find_all('td')
print(rows[1].text.strip())
producttype=rows[1].text.strip()
vendor=rows[2].text.strip()
product=rows[3].text.strip()
version=rows[4].text.strip()
# product = rows[1].text.strip()item={}
item['cveid'], item['score'], item['vulntype'], item['producttype'], item['vendor'], item['product'], item[
'version'] =cveid, score, vulntype,producttype, vendor, product, versionprint(item)
if__name__=='__main__':
# 爬取数据的起始页码和返回的数据条数# start_page = 1# num_records = 10# get_cve_data(start_page, num_records)d1=pd.read_excel('all_spyder(中文).xlsx')
exist_cv1=d1['cve'].tolist()
d1=pd.read_excel('output(2015).xlsx')
exist_cv2=d1['cveid'].tolist()
exist_cv1.extend(exist_cv2)
exist_cv1=list(set(exist_cv1))
print(exist_cv1[:10])
crawler_tool=CveDetailSpider2()
crawler_tool.parse(start_y=2017,end_y=2017)
目录
相关文章
|
8天前
|
机器学习/深度学习 算法 数据挖掘
6种有效的时间序列数据特征工程技术(使用Python)
在本文中,我们将探讨使用日期时间列提取有用信息的各种特征工程技术。
33 0
|
9天前
|
算法 Python
Python 中的数据抽象
【8月更文挑战第29天】
22 11
|
7天前
|
数据采集 JavaScript 前端开发
构建简易Python爬虫:抓取网页数据入门指南
【8月更文挑战第31天】在数字信息的时代,数据抓取成为获取网络资源的重要手段。本文将引导你通过Python编写一个简单的网页爬虫,从零基础到实现数据抓取的全过程。我们将一起探索如何利用Python的requests库进行网络请求,使用BeautifulSoup库解析HTML文档,并最终提取出有价值的数据。无论你是编程新手还是有一定基础的开发者,这篇文章都将为你打开数据抓取的大门。
|
9天前
|
JSON 数据格式 Python
Python快速获取国内最新放假安排数据
Python快速获取国内最新放假安排数据
|
10天前
|
存储 数据可视化 Python
使用python moviepy提取视频中的音频,同时对音频数据进行数据可视化分析
使用python moviepy提取视频中的音频,同时对音频数据进行数据可视化分析
9 0
|
5天前
|
存储 消息中间件 大数据
Python里for循环要遍历的数据很多很大怎么办?
遇到大数据量问题时,重要的是确定最优解决方案,这取决于数据的来源、性质以及所需的处理方式。分析数据传输、存储与处理的瓶颈是提升性能的关键。通过结合上述的技巧和方法,可以在内存和性能方面找到合适的平衡点来处理大规模数据集。
14 0
|
7天前
|
Java 开发者 关系型数据库
JSF与AWS的神秘之旅:如何在云端部署JSF应用,让你的Web应用如虎添翼?
【8月更文挑战第31天】在云计算蓬勃发展的今天,AWS已成为企业级应用的首选平台。本文探讨了在AWS上部署JSF(JavaServer Faces)应用的方法,这是一种广泛使用的Java Web框架。通过了解并利用AWS的基础设施与服务,如EC2、RDS 和 S3,开发者能够高效地部署和管理JSF应用。文章还提供了具体的部署步骤示例,并讨论了使用AWS可能遇到的挑战及应对策略,帮助开发者更好地利用AWS的强大功能,提升Web应用开发效率。
31 0
|
7天前
|
数据采集 存储 数据库
Python中实现简单爬虫与数据解析
【8月更文挑战第31天】在数字化时代的浪潮中,数据成为了新的石油。本文将带领读者通过Python编程语言,从零开始构建一个简单的网络爬虫,并展示如何对爬取的数据进行解析和处理。我们将一起探索请求网站、解析HTML以及存储数据的基础知识,让每个人都能成为自己数据故事的讲述者。
|
7天前
|
Python
Python魔法:用一行代码实现数据排序
【8月更文挑战第31天】忘掉传统多行排序代码,本文揭秘如何使用一行Python代码快速对数据进行排序,同时深入探讨背后的原理和性能考量。
|
7天前
|
数据采集 JavaScript 前端开发
构建你的第一个Python爬虫:抓取网页数据入门指南
【8月更文挑战第31天】在数字时代,数据是新的石油。本文将引导初学者通过简单的步骤,使用Python编程语言创建一个基础的网络爬虫程序。我们将探索如何从网络上提取信息,并理解背后的原理。无论你是编程新手还是想要扩展你的技术工具箱,这篇文章都将为你提供一条清晰的道路,让你学会编写能够自动获取网络数据的脚本。准备好开始你的网络数据抓取之旅了吗?让我们现在就开始吧!
下一篇
DDNS