python3实现⽂章爬取
基于搜狗的⽂章爬取
前⾔:⽂章仅⽤于学习交流,不⾜之处欢迎⼩伙伴指正!
⼀、功能介绍:
已实现功能:
1、爬取搜狗上的分类⼀栏的所有事件及其他的所有标题事件和加载更多,返回⽂章链接与标题,并存⼊数据库中,后续可直接根据链接下载⽂章。
2、根据输⼊内容定向爬取⽂章,返回链接与标题。
待实现功能:
1、根据数据库中的链接爬取的所有相关⽂章,保存于数据库,并对所有⽂章分类存档。
2、实现UI界⾯(PyQt5),根据需要对程序打包为可执⾏⽂件。
⼆、运⽤到的知识点介绍:
selenisum(实现简单的搜狗主页源码获取)
代理池原理  (给定ip源,简单的判断ip是否可⽤)
线程池原理    (实现多线程爬取,增加爬取效率)
oo⾯向思想    (⾯向对象编程,分模块编程,增加可读性,⽅便后期维护)
⼀些常⽤的库    (os、time、random、requests、pymysql、queue、threading)
c语言课程设计总结500字三、⽂件的结构组成及功能说明
1、main.py:该⽂件为程序的⼊⼝,即启动⽂件,功能:⼏个模块之间的数据传输的中转站。
2、ip_pool.py:  该⽂件是ip代理池⽂件, 功能:将给定的ip列表进⾏筛选,选出可⽤的ip⽅便后续请求。
2、spider_page.py:  该⽂件⽤于提取⽹页源码, 功能:selenisum去获取主页源码。
3、settings.py:该⽂件为配置⽂件, 功能:我们在程序启动之前可以选择爬⾍的爬取⽅向,当然这个⽅向是由⾃⼰给定的。
4、is_API_Run.py:  该⽂件是API执⾏⽂件,功能:根据settings⽂件的配置输⼊,从⽽决定执⾏那些API函数。
5、API_Function.py:  该⽂件是API⽂件,功能:实现了各个API函数的功能实现。
6、thread_pool.py:该⽂件为线程池⽂件,功能:实现了从数据库中获取链接,去多线程的下载⽂章。
四、程序运⾏步骤代码解读
2、⽂章这⾥以主页中的 “搜索热词”、“编辑精选”、“热点⽂章”、“热门”举例演⽰。
3、从main⽂件的程序⼊⼝启动程序,⾸先该⽂件导⼊了⼀些包和编写的其他模块⽂件,并编写了相应的两个函数,分别是panding()函数、ip()函数,对应功能见代码注释,其他的⼀些模块⽂件在后边会有解释
⽂件名:main.py
'''
启动程序
'''
#导包和导⼊⾃定义模块⽂件
#⾃⼰编写的模块⽂件
#⾃⼰编写的模块⽂件
from spider_page import __init__source
from is_API_Run import read_settings_run_func
from thread_pool import Open_Thread_Assign_Links
from ip_pool  import ip_Pool
#python包
import os
import time
import random
def ip(IP_POOL):
'''
从IP_POOL(ip池)随机选出⼀个ip将其返回给主程序使⽤,
:param IP_POOL: IP池
:return: proxies ------随机的⼀个代理ip
'''
proxies = {
"http": random.choice(IP_POOL),
}
return proxieswebsocket java实现
def panding(proxies):
'''在此处实现:判断⼯作⽂件路径下的page_source⽬录下是否有名为当⽇的⽂件()--年⽉⽇的txt⽂件,
判断⽂件名是否符合要求(⼀天之内⽣成的)若有则读取出来赋值page,返回给主程序使⽤,若没有则执⾏page=__init__source().html_source语句。获取⽹页源代码,再将其命名保存,并且返回给主程序使⽤'''
work_path = os.getcwd()  # 获取⼯作路径
html_path = os.path.join(work_path, 'page_source')
if len(os.listdir(html_path)) > 0:  # 判断路径下是否有⽂件
flag = False
for x in os.listdir(html_path):  # 罗列出路径下所有的⽂件
print("x:", x)
if x == (time.strftime(r'%Y%m%d') + r'.txt'):  # 出当天⽣成的⽂件
print("x:", x)
with open(os.path.join(html_path, x), 'r', encoding="utf-8") as f:
page = f.read()
return page
# 没有当天的⽂件就创建⽂件并写⼊html源码
page = __init__source(proxies).html_source
with open(os.path.join(html_path, time.strftime(r'%Y%m%d') + r'.txt'), 'w', encoding="utf-8") as f:
f.write(page)
else:
page = __init__source(proxies).html_source
with open(os.path.join(html_path, time.strftime(r'%Y%m%d') + r'.txt'), 'w', encoding="utf-8") as f:
f.write(page)
return page            #将源码返回给主程序使⽤python在线编辑器python3
if __name__ == '__main__':
IP_POOL = ip_Pool()  # 启动ip代理池  (初始化ip类,并⽣成代理池对象,接下来从对象中获取ip池---IP_POOL.ip_pool)
proxies = ip(IP_POOL.ip_pool)  # 随机从ip池中拿出⼀个代理ip---proxies
page = panding(proxies)  # 初始化源码(⽤代理ip请求主页源码,并保存于程序⼯作⽬录下的page_source⽂件夹下的以年⽉⽇为名的txt⽂件。)
read_settings_run_func(page, proxies)  # 读取配置⽂件并执⾏相应的API函数。
Open_Thread_Assign_Links(proxies)  # 开启线程池下载⽂章
4、然后解释⼀下ip代理池这个模块⽂件,该⽂件实现了动态的从⽹上的ip源获取可⽤ip,并初始化IP
代理池为5个ip,然后会在主程序运⾏
过程中⼀直对ip池中的ip进⾏可⽤性验证,若ip过期不可⽤,那将该ip从ip代理池中删除,再从ip源获取可⽤ip补充ip代理池。具体功能实现
见代码。该⽂件模块可以拿出来单独使⽤,并不局限于单独的某个程序。单独使⽤⽅法,后⾯会有具体说明。
⽂件名:ip_pool.py
# 导包
import requests
import time
import re
import threading
# 定义测试的url链接,这⾥暂且选⽤www.baidu
url = 'www.baidu/'
# 定义测试的url链接www.baidu的请求头。
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Cache-Control': 'max-age=0',
'Connection': 'keep-alive',
'Cookie': 'BIDUPSID=EAAEC44F956EC0051F3EB986A600267F; PSTM=1618841564; BD_UPN=12314753; __yjs_duid=1_fc17df5ce48c903e96c35412849fa9c    'Host': 'www.baidu', 'Referer': 'https', 'Sec-Fetch-Dest': 'document', 'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'cross-site', 'Sec-Fetch-User': '?1', 'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36 SLBrowser/7.0.0.4071 S
# 对url⽹站发起请求,根据返回体的状态码判断是否请求成功,若成功则该ip可⽤,若不成功则ip不可⽤,将ip从ip池中移除。
# 那么这个ip池要保证在整个程序运⾏⽤ip皆可⽤
# ip供应源(ip_source)
ip_source = 'ip源'
# 初始化ip池为空(Ip_Pool)
Ip_Pool = []
# ip的预期存留时间M
M = 0
# ip代理池类
class ip_Pool:
def __init__(self, ):
self.ip_pool = []  # 初始化ip池属性,⽅便后续的ip池赋值。
threading.Thread(urn_ip_pool).start()  # 开启⼦线程动态处理ip代理池,⽬的:保证ip池中ip的可⽤性的同时,⼜不会影响其他程序运⾏。所以开辟        time.sleep(6)  # 加这个等待时间,⽬的:给⼦线程⾜够的时间去获取ip,并填充ip池,保证返回给主程序的ip池不为空。
def ip_yield(self):
while True:
jquery手写图片大全
while len(Ip_Pool) < 5:  # 这⾥的while循环语句⽬的:⽤于检测ip池中是否始终满⾜个数要求
ip = (ip_source).text  # 从ip源获取ip⽂本。
if '{' in ip:  # 检测从ip源是否成功获取到ip。若未获取到ip则会返回⼀个包含字典样式的字符串。
continue
# time.sleep(0.5)    # 可以增加等待时间,以提⾼获取到ip的成功率
else:
ip = re.match('\S*', ip).group()  # 对获取到的ip⽂本简单处理,⽬的去除\r\n字符。
Ip_Pool.append(ip)  # 将ip添加到ip池中。
# 暂停M分钟,并将Ip_Pool返回出去使⽤
yield Ip_Pool
time.sleep(M)
print('将IP池返回给主程序使⽤------' + str(M) + '半分钟后对IP池进⾏检测是否可⽤--------')
#以下for循环是⽤于检测ip池中ip是否过期。
for x in Ip_Pool:
proxies = {'http': x}
proxies = {'http': x}
try:
(url, proxies=proxies, headers=headers).status_code == 200:
# print('该ip正常,还能继续使⽤半分钟')
pass
except Exception:
print('存在⼀个ip过期,即将从IP池中去除该ip')
ve(x)
def return_ip_pool(self):
print("ip池线程启动")
for self.ip_pool in self.ip_yield():
pass
5、若需要使⽤该ip池模块,则需要将⽂件copy于使⽤的⽂件⽬录下,然后导⼊⽂件模块,再创建ip代理类对象,⽤对象获取ip池
(ip_pool)。
6、咱们来回顾下,主程序启动ip代理池后得到ip池,使⽤ip()⽅法将ip池处理得到⼀个随机ip,将ip放⼊panding⽅法中请求得到主页源码,再调⽤is_API_Run.py⽂件模块下的read_settings_run_func类,继⽽传⼊源码创建类对象,在这个⽂件模块中导⼊API模块和配置模块,具体功能:根据配置模块创建配置类对象,从⽽获取到配置信息。然后由API模块创建API类对象,根据配置信息执⾏相应的⽅法。以下⽂件中的打印内容都可以去掉,换成pass占位即可
⽂件名:is_API_Run.py
'''
获取配置⽂件settings的输⼊给与相应的函数输出
'''
from API_Function import Functions
from settings import configure
class read_settings_run_func():
def __init__(self, page, proxies):
self.proxies = proxies
self.page = page
self.set = configure()
self.func = Functions(self.page, self.proxies)
def test_settings(self):
if self.set.Search_hot_words == True:
self.func.Search_hot_words()
else:
print("mei")
if self.set.Editor_s_selection == True:
self.func.Editor_s_selection()
else:
print("mei")
if self.set.Hot_articles == True:
self.func.Hot_articles()
织梦人在线阅读
else:
print("mei")
if self.set.Custom_hotspot_source_Text == True:
self.func.Custom_hotspot_source_Text(_list)
else:
print("mei")
if self.set.Custom_hotspot_source_Url == True:
self.func.Custom_hotspot_source_Url(self.set.Custom_hotspot_source_Url_List)
else:
print("mei")
if self.set.Hot_event_sources_of_other_websites == True:
self.func.Hot_event_sources_of_other_websites(self.set.Hot_event_sources_of_other_websites_List)        else:
print("mei")
if self.set.input_text == True:
self.func.input_text()
else:
print("mei")
if self.set.Crawling_article == True:
self.func.Crawling_article()
else:
print("mei")
if self.set.Crawling_official_account == True:
self.func.Crawling_official_account()
else:
print("mei")
if self.set.Hot == True:
self.func.Hot()
else:
print("mei")
if self.set.Funny == True:
self.func.Funny()
else:
print("mei")
if self.set.Honyaradoh == True:
self.func.Honyaradoh()
else:
print("mei")
if self.set.Private_talk == True:
self.func.Private_talk()
else:
print("mei")
if self.set.Eight_trigrams == True:
self.func.Eight_trigrams()
else:
print("mei")
if self.set.Technocrats == True:
self.func.Technocrats()
else:
print("mei")
if self.set.Financial_fans == True:
self.func.Financial_fans()
else:
print("mei")
if self.set.Car_control == True:
self.func.Car_control()
else:
mysql配置文件路径print("mei")
if self.set.Life_home == True:
self.func.Life_home()

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。