版权声明:欢迎读阅 https://blog.csdn.net/weixin_44266137/article/details/88657615
我这里把很多东西写死了。就放一些逻辑在里边。
完整代码如下
其中用到了模拟浏览器请求。原因是因为requests抓取和模拟浏览器抓取下来的内容不一致。你会很纠结。感兴趣的可以试试。
# -*- encoding: utf-8 -*-
# 导包
import gevent
# 猴子补丁
from gevent import monkey
monkey.patch_all()
import requests
import os
import re
from lxml import etree
import time
# 模拟浏览器行为
from selenium import webdriver
# 定义全局变量
global_url_list = []
# 定义抓取类
class GeventSpider(object):
# 定义类属性
encloseing_url_list = []
# 定义爬取内页的方法
def get_inner(self,url):
# 发送请求
r = requests.get(url)
html = r.content.decode('utf-8')
# 正则比配标题
regex = re.compile('<h1><!--repaste.title.begin-->(.+?)<!--repaste.title.end--><\/h1>',re.I)
# 匹配模式不区分大小写
print(regex.findall(html))
# 定义数据匹配方法
def get_xpath(self,html):
# 初始化xml
html = etree.HTML(html)
# 匹配url
html_data_url = html.xpath('//span[@class="l"]/a/@href')
# 修改全局变量
global global_url_list
global_url_list = html_data_url
self.encloseing_url_list = global_url_list
# print(len(html_data_url))
# 定义抓取方法
def run(self,url):
# print(url)
# 抓取文件
if url == 'http://military.cctv.com/':
file_name = 'test_cctv.html'
else:
file_name = 'inner_cctv.html'
# 使用os模块来判断文件是否存在
# 方法返回布尔值
html_content = ''
if not os.path.exists(file_name):
# 发送http请求
# res = requests.get(url)
# 定义浏览器对象
browser = webdriver.Chrome()
# 发送请求
browser.get(url)
# 解码赋值
html = browser.page_source.encode('utf-8').decode()
# 解码
# html = res.content.decode('utf-8')
time.sleep(20)
# 写文件 指定文件编码
with open('./'+file_name,'w',encoding='utf-8') as f:
f.write(html)
browser.quit()
html_content = html
# 关闭浏览器
else:
# 读取文件返回 默认第二个参数是 w
with open('./'+file_name,encoding='utf-8') as f:
contents = f.read()
html_content = contents
# 检查
# print(html_content)
self.get_xpath(html_content)
if __name__ == "__main__":
# 实例化对象
geventspider = GeventSpider()
# 定义一个urllist
url_list = ['http://military.cctv.com/']
# 第一种方法
# 定义任务列表
# job_list = []
# for i in url_list:
# # 启动协程
# job_list.append(gevent.spawn(geventspider.run,i))
# 定义第二种方法(列表推导式) 性能更好,效率更好
# job_list = [gevent.spawn(geventspider.run,i) for i in url_list]
# # # 阻塞协程
# gevent.joinall(job_list)
# 请求首页没必要开协程
geventspider.run(url_list[0])
# 使用协程同时爬取14条内页
url_list = geventspider.encloseing_url_list
job_list = [gevent.spawn(geventspider.get_inner,url) for url in url_list]
gevent.joinall(job_list)
# print(global_url_list)
# print(geventspider.encloseing_url_list)
geventspider.get_inner(url_list[0])
# print(url_list)