版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
通用爬虫教学课件什么是网络爬虫网络爬虫是一种自动抓取互联网数据的软件或脚本,它能够根据预设规则自动访问网页,获取所需信息,并将数据保存下来供后续分析使用。随着互联网的快速发展,全球数据量呈现爆炸式增长。据统计,互联网数据体量每年以40%以上的速度增长,这意味着全球数据总量约每两年就会翻一番。在大数据时代,各行业的数据分析工作有超过90%依赖于从非结构化网页中抓取的数据。这些数据成为企业决策、市场分析、学术研究的重要基础。爬虫技术作为获取这些海量数据的关键工具,已经成为数据科学家、开发工程师必备的技能之一。从简单的数据抓取到复杂的分布式爬虫系统,网络爬虫在各个领域都有广泛应用。自动化数据采集无需人工操作,可以24小时不间断工作,高效获取海量数据高速数据处理现代爬虫系统可以并发处理成千上万个网页,速度远超人工收集定制化数据结构爬虫的主要应用场景1搜索引擎索引搜索引擎通过爬虫程序持续收集互联网上的网页内容,建立索引并提供搜索服务。以百度和Google为例,它们的网页收录量已超过千亿条,每天还有数以亿计的新增内容需要处理。搜索引擎爬虫不仅收集文本内容,还会处理图片、视频等多媒体资源,是最大规模的爬虫应用。2市场行情监测企业通过爬虫自动收集电商平台商品价格、房产网站房源信息、招聘网站职位数据等市场行情,用于竞争分析和市场决策。例如,电商企业会通过爬虫监控竞争对手的价格变化,实时调整自身定价策略;房地产分析师利用爬虫收集各区域房价走势,预测市场变化。3舆情分析与学术研究通过爬取社交媒体、新闻网站、论坛等平台的内容,分析公众对特定事件、品牌或产品的情感倾向和意见分布。学术研究者利用爬虫收集大量原始数据进行科学研究,如语言学研究者抓取网络文本分析语言变化,社会学家收集社交网络数据研究群体行为。4竞品情报与风险控制企业通过爬虫收集竞争对手的产品信息、价格策略、营销活动等情报,为战略决策提供依据。爬虫生态与发展现状Python主导的爬虫生态在中国的爬虫开发项目中,Python占据了约70%的市场份额,成为绝对主流的爬虫开发语言。Python凭借其简洁的语法、丰富的第三方库和强大的社区支持,成为爬虫开发的首选语言。主流Python爬虫库的活跃度和下载量持续增长:Requests库月下载量超过5000万次BeautifulSoup在GitHub上有超过10000颗星Scrapy框架拥有40000+星标,成为最受欢迎的爬虫框架Selenium在爬虫和自动化测试领域双向发力爬虫技术发展趋势随着反爬技术的不断升级,爬虫技术也在持续演化:基于机器学习的智能爬虫系统正在兴起分布式爬虫架构成为大规模数据采集的标准云服务提供商开始提供专业的爬虫云服务各大企业纷纷建立自有爬虫平台和定制化解决方案通用爬虫技术基础1HTTP协议基础HTTP(超文本传输协议)是爬虫技术的基石,它定义了客户端与服务器之间的通信规则。请求方法:GET(获取资源)、POST(提交数据)、HEAD(获取头信息)等请求头:包含User-Agent、Referer、Cookie等关键信息状态码:200(成功)、404(未找到)、403(禁止访问)、500(服务器错误)等响应头:包含Content-Type、Content-Length、Set-Cookie等信息2浏览器与服务端通信原理了解浏览器如何与服务器进行通信,是编写有效爬虫的关键:DNS解析:将域名转换为IP地址TCP连接:建立客户端与服务器的连接发送HTTP请求:浏览器向服务器发送请求服务器处理:服务器解析请求并生成响应接收响应:浏览器接收并处理服务器返回的数据渲染页面:浏览器解析HTML、CSS和JavaScript,渲染页面3网页数据的组织与传输现代网页数据的组织形式多样,爬虫需要处理各种数据格式:HTML:网页的基本结构,包含文本、链接、表格等CSS:定义网页的样式和布局JavaScript:提供交互功能和动态内容JSON:轻量级数据交换格式,常用于API响应XML:可扩展标记语言,用于存储和传输数据网页结构基础HTML/DOM树结构HTML(超文本标记语言)是构建网页的标准语言,通过标签定义网页元素和结构。浏览器将HTML解析为DOM(文档对象模型)树,代表网页的结构化表示。DOM树由节点组成,包括:文档节点:整个HTML文档的根节点元素节点:HTML标签如<div>、<p>、<a>等属性节点:元素的属性,如id、class、href等文本节点:元素内的文本内容注释节点:HTML中的注释内容了解DOM树结构是准确定位和提取网页数据的基础。网页元素定位技术XPath是XML路径语言,用于在XML文档中导航和选择节点://div[@class='product']//h2#选择class为product的div下的所有h2元素//a[@href]#选择所有有href属性的a元素//table//tr[position()>1]#选择表格中除第一行外的所有行CSS选择器使用类似CSS的语法定位元素:ducth2#选择class为product的div下的所有h2元素a[href]#选择所有有href属性的a元素tabletr:not(:first-child)#选择表格中除第一行外的所有行爬虫的数据抓取流程发送请求爬虫通过模拟浏览器行为发送HTTP请求到目标网站服务器。这一阶段需要关注:请求头设置:模拟真实用户的User-Agent、Referer等Cookie管理:处理需要登录或身份验证的网站请求参数:URL参数、表单数据等请求方法选择:GET、POST等代理IP使用:防止IP被封禁请求频率控制:避免对服务器造成过大压力解析响应服务器返回响应后,爬虫需要解析各种格式的数据:HTML解析:使用BeautifulSoup、lxml等库解析HTML结构JSON解析:处理API返回的JSON数据XML解析:解析结构化的XML响应二进制数据处理:下载图片、文件等编码处理:处理不同字符编码的响应动态内容渲染:处理JavaScript生成的内容数据清洗和存储抓取的原始数据通常需要进一步处理才能使用:数据清洗:去除无用内容、修复缺失值、格式统一化数据转换:将非结构化数据转为结构化数据数据验证:确保数据的完整性和准确性数据存储:保存到文件(CSV、JSON、Excel)或数据库(MySQL、MongoDB)数据更新:定期更新和维护数据集处理动态页面静态页面与动态页面的区别现代网站越来越多地使用JavaScript动态生成内容,这给传统爬虫带来了挑战:静态页面:服务器直接返回完整HTML,源代码中包含所有内容动态页面:初始HTML只是框架,真实内容通过JavaScript异步加载检测页面是否动态的方法:查看网页源代码与浏览器开发者工具中的DOM是否一致搜索关键内容是否出现在源代码中检查是否有大量AJAX请求或React/Vue等前端框架处理动态内容的技术浏览器自动化方案:Selenium:控制真实浏览器执行JavaScript渲染Puppeteer:基于HeadlessChrome的自动化工具Playwright:支持多浏览器的自动化框架接口抓包与AJAX分析:通过浏览器开发者工具分析网站的API请求直接请求数据接口绕过前端渲染Robots.txt与爬虫礼仪理解Robots协议Robots.txt是网站根目录下的一个文本文件,用于告诉爬虫哪些页面可以访问,哪些不能访问。它是网络爬虫应该遵守的基本礼仪规范。Robots.txt示例:User-agent:*#适用于所有爬虫Disallow:/admin/#禁止访问admin目录Disallow:/private/#禁止访问private目录Allow:/public/#允许访问public目录Crawl-delay:10#每次请求间隔10秒尊重Robots.txt是负责任爬虫的基本原则,但它并非强制性的技术限制,而是一种道德约定。爬虫礼仪与最佳实践除了遵守Robots.txt,一个有礼貌的爬虫还应该:使用合理的User-Agent设置合适的User-Agent标识,不要刻意隐藏爬虫身份。如果是商业用途,最好使用包含联系方式的标识。控制请求频率避免短时间内发送大量请求,合理设置爬取间隔,遵守网站的Crawl-delay指令,防止给服务器带来过大负载。避开高峰时段选择网站流量较低的时段进行爬取,如夜间或周末,减少对网站正常服务的影响。遵守数据使用规定查看网站的服务条款和隐私政策,确保你的数据使用方式不违反网站规定,尤其是商业用途时。爬虫开发常用库介绍Requests库Python最流行的HTTP客户端库,简单易用,用于发起HTTP请求获取网页内容。安装:pipinstallrequests特点:简洁的API、自动处理cookies、支持各种认证方式、处理重定向和超时BeautifulSoup库强大的HTML/XML解析工具,用于从网页中提取数据。安装:pipinstallbeautifulsoup4特点:简单易学、容错能力强、支持多种解析器、提供导航和搜索DOM树的方法Lxml/Html5lib不同的HTML解析器,各有特点。Lxml基于C语言,速度快但对格式要求高;Html5lib基于浏览器渲染引擎,容错性强但速度较慢。安装:pipinstalllxmlhtml5libSelenium浏览器自动化工具,可控制真实浏览器执行各种操作,适合处理JavaScript渲染的动态页面。安装:pipinstallselenium特点:可模拟真实用户行为、支持多种浏览器、能处理复杂交互场景Scrapy全功能的爬虫开发框架,提供了爬取、处理、存储的完整流程支持。安装:pipinstallscrapyRequests库核心用法基本请求方法importrequests#GET请求response=requests.get('')print(response.text)#打印响应内容print(response.status_code)#打印状态码#带参数的GET请求params={'key1':'value1','key2':'value2'}response=requests.get('/search',params=params)print(response.url)#打印完整URL#POST请求data={'username':'user','password':'pass'}response=requests.post('/login',data=data)print(response.json())#解析JSON响应自定义请求头headers={'User-Agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36','Referer':'','Accept-Language':'zh-CN,zh;q=0.9'}response=requests.get('',headers=headers)Cookie与会话管理#使用Session保持Cookiesession=requests.Session()session.get('/login')#获取初始Cookieresponse=session.post('/login',data={'username':'user','password':'pass'})#登录后的请求会自动带上Cookieprofile=session.get('/profile')超时与重试机制#设置超时try:response=requests.get('',timeout=5)exceptrequests.Timeout:print("请求超时")#带重试的请求fromrequests.adaptersimportHTTPAdapterfromurllib3.util.retryimportRetryretry_strategy=Retry(total=3,#最多重试3次backoff_factor=1,#重试间隔status_forcelist=[500,502,503,504]#这些状态码时重试)adapter=HTTPAdapter(max_retries=retry_strategy)session=requests.Session()session.mount("https://",adapter)session.mount("http://",adapter)response=session.get('')代理设置BeautifulSoup核心用法创建BeautifulSoup对象frombs4importBeautifulSoup#从HTML字符串创建html="""<html><body><h1class="title">HelloWorld</h1><pclass="content">Thisisaparagraph.</p><ulid="list"><li>Item1</li><li>Item2</li></ul></body></html>"""#选择解析器:html.parser(Python内置),lxml(速度快),html5lib(最准确)soup=BeautifulSoup(html,'lxml')#从文件创建withopen('page.html','r')asf:soup=BeautifulSoup(f,'html.parser')#与requests结合使用importrequestsresponse=requests.get('')soup=BeautifulSoup(response.text,'lxml')查找元素方法正则表达式提取数据正则表达式基础正则表达式是一种强大的文本模式匹配工具,特别适合从非结构化文本中提取特定格式的数据。importre#基本匹配text="我的电话是123-4567-8901"pattern=r"\d{3}-\d{4}-\d{4}"result=re.search(pattern,text)ifresult:print(result.group())#输出:123-4567-8901#匹配多个结果text="联系方式:123-4567-8901或987-6543-2109"pattern=r"\d{3}-\d{4}-\d{4}"results=re.findall(pattern,text)print(results)#输出:['123-4567-8901','987-6543-2109']#使用分组提取text="姓名:张三,邮箱:zhangsan@"pattern=r"姓名:(.*?),邮箱:(.*?)$"result=re.search(pattern,text)ifresult:name,email=result.groups()print(f"姓名:{name},邮箱:{email}")常用正则表达式模式数据类型正则表达式电子邮箱r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'中国手机号r'1[3-9]\d{9}'URLr'https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+'IP地址r'\b(?:\d{1,3}\.){3}\d{1,3}\b'中国身份证号r'\d{17}[\dXx]'正则表达式与BeautifulSoup结合Selenium自动化爬虫Selenium环境配置Selenium需要与浏览器驱动配合使用,常用的有:ChromeDriver:配合GoogleChrome浏览器geckodriver:配合Firefox浏览器MicrosoftEdgeDriver:配合Edge浏览器#安装Seleniumpipinstallselenium#下载对应浏览器版本的驱动#Chrome:/downloads#Firefox:/mozilla/geckodriver/releases基本使用方法fromseleniumimportwebdriverfromselenium.webdriver.chrome.serviceimportServicefrommon.byimportByimporttime#设置ChromeDriver路径service=Service('/path/to/chromedriver')driver=webdriver.Chrome(service=service)#访问网页driver.get('')#等待页面加载(建议使用显式等待,这里用简单的sleep示例)time.sleep(2)#获取页面标题print(driver.title)#关闭浏览器driver.quit()元素定位与操作#定位元素#By.ID,By.NAME,By.CLASS_NAME,By.TAG_NAME,By.LINK_TEXT,#By.PARTIAL_LINK_TEXT,By.XPATH,By.CSS_SELECTOR#输入文本search_box=driver.find_element(By.NAME,'q')search_box.send_keys('SeleniumPython')#点击按钮submit_button=driver.find_element(By.CSS_SELECTOR,'input[type="submit"]')submit_button.click()#获取文本results=driver.find_elements(By.CSS_SELECTOR,'.result')forresultinresults:print(result.text)处理动态内容和交互Scrapy框架详解Scrapy架构组件Scrapy是一个功能完整的爬虫框架,采用组件化设计,各部分协同工作:Engine:核心引擎,负责组件间数据流和信号的传递Spider:用户编写的爬虫类,定义如何抓取和解析页面Scheduler:调度器,接收请求并安排执行顺序Downloader:下载器,负责获取网页内容并返回响应ItemPipeline:项目管道,负责处理爬取到的数据Middleware:中间件,处理请求和响应,实现功能扩展项目结构与创建#安装Scrapypipinstallscrapy#创建新项目scrapystartprojectexample_project#项目结构example_project/├──scrapy.cfg#部署配置文件└──example_project/#Python模块目录├──__init__.py├──items.py#数据定义├──middlewares.py#中间件├──pipelines.py#数据处理├──settings.py#项目设置└──spiders/#爬虫目录└──__init__.py#创建爬虫cdexample_projectscrapygenspiderexampleSpider示例代码#spiders/example.pyimportscrapyfromexample_project.itemsimportProductItemclassExampleSpider(scrapy.Spider):name="example"#爬虫名称allowed_domains=[""]#允许爬取的域名start_urls=["/products"]#起始URLdefparse(self,response):#提取商品列表forproductinresponse.css('duct'):item=ProductItem()item['name']=product.css('h2::text').get()item['price']=product.css('span.price::text').get()item['url']=product.css('a::attr(href)').get()yielditem#处理分页next_page=response.css('a.next::attr(href)').get()ifnext_page:yieldresponse.follow(next_page,self.parse)Item与Pipeline多线程与异步爬虫并发爬虫的必要性当需要爬取大量页面时,单线程爬虫效率低下。使用并发技术可以显著提高爬取速度:利用CPU多核性能,同时处理多个任务在I/O等待期间执行其他任务,避免空闲可以模拟多用户同时访问,更自然但并发爬虫也面临挑战:需要控制并发数量,避免对服务器压力过大处理复杂的线程同步和资源竞争问题容易触发网站的反爬机制多线程爬虫实现importrequestsfrombs4importBeautifulSoupimportthreadingimportqueueimporttime#初始化URL队列url_queue=queue.Queue()foriinrange(1,11):url_queue.put(f'/page/{i}')#定义爬虫线程defcrawler_thread():whilenoturl_queue.empty():url=url_queue.get()try:response=requests.get(url)soup=BeautifulSoup(response.text,'html.parser')#处理数据...print(f"爬取{url}成功")exceptExceptionase:print(f"爬取{url}失败:{e}")finally:#完成任务url_queue.task_done()#添加延迟,避免请求过快time.sleep(1)#创建并启动多个线程thread_num=5threads=[]foriinrange(thread_num):t=threading.Thread(target=crawler_thread)t.daemon=Truethreads.append(t)t.start()#等待所有任务完成url_queue.join()异步爬虫实现importaiohttpimportasynciofrombs4importBeautifulSoupasyncdeffetch(session,url):try:asyncwithsession.get(url)asresponse:returnawaitresponse.text()exceptExceptionase:print(f"爬取{url}失败:{e}")returnNoneasyncdefparse(html):ifhtml:soup=BeautifulSoup(html,'html.parser')#处理数据...return"数据处理结果"returnNoneasyncdefcrawl(url):asyncwithaiohttp.ClientSession()assession:html=awaitfetch(session,url)result=awaitparse(html)print(f"处理{url}完成")returnresultasyncdefmain():urls=[f'/page/{i}'foriinrange(1,11)]#创建任务tasks=[]forurlinurls:#控制并发,避免同时发送太多请求awaitasyncio.sleep(0.5)tasks.append(asyncio.create_task(crawl(url)))#等待所有任务完成results=awaitasyncio.gather(*tasks)returnresults#运行异步主函数if__name__=="__main__":results=asyncio.run(main())print(f"共爬取{len(results)}个页面")GIL与并发性能Python的全局解释器锁(GIL)限制了多线程在CPU密集型任务上的性能,但在I/O密集型任务(如网络爬虫)上影响较小:爬虫主要是I/O密集型任务,大部分时间在等待网络响应多线程可以在一个线程等待I/O时执行其他线程的代码对于CPU密集型任务(如复杂数据处理),考虑使用多进程数据清洗与持久化1数据清洗流程爬取的原始数据通常需要进行一系列处理才能使用:数据去重:删除重复记录,避免数据冗余缺失值处理:补全或移除缺失数据数据转换:将文本转换为适当的数据类型(数字、日期等)数据规范化:统一格式,如电话号码、地址等数据验证:检查数据的有效性和准确性数据过滤:移除不相关或不需要的信息#简单数据清洗示例importpandasaspd#假设data是从网页抓取的数据列表data=[{"name":"产品A","price":"¥199.00","stock":"有货"},{"name":"产品B","price":"缺货","stock":"无货"},{"name":"产品A","price":"¥199","stock":"有货"}]#转换为DataFramedf=pd.DataFrame(data)#去重df=df.drop_duplicates(subset=['name'])#处理价格-提取数字df['price']=df['price'].str.extract(r'(\d+)')#转换库存状态为布尔值df['in_stock']=df['stock'].apply(lambdax:x=="有货")print(df)2文件存储方式处理后的数据可以保存为多种格式:#保存为CSVdf.to_csv('products.csv',index=False,encoding='utf-8-sig')#保存为Exceldf.to_excel('products.xlsx',index=False)#保存为JSONimportjsonwithopen('products.json','w',encoding='utf-8')asf:json.dump(data,f,ensure_ascii=False,indent=2)#保存为XMLimportdicttoxmlfromxml.dom.minidomimportparseStringxml=dicttoxml.dicttoxml(data)dom=parseString(xml)pretty_xml=dom.toprettyxml()withopen('products.xml','w',encoding='utf-8')asf:f.write(pretty_xml)3数据库存储对于大量数据或需要频繁查询的场景,数据库是更好的选择:常见反爬机制识别验证码类型与破解验证码是网站最常用的反爬机制之一:图形验证码:包含扭曲文字或数字的图片滑块验证码:需要拖动滑块到指定位置点选验证码:要求点击特定物体或按顺序点击行为验证码:分析用户行为判断是否为机器人应对方法:简单图形验证码可使用OCR技术识别复杂验证码可使用人工识别服务使用机器学习模型训练识别IP封禁与限频网站通过监控请求频率和模式识别爬虫:频率限制:短时间内限制请求次数IP封禁:直接封禁可疑IP地址访问模式检测:识别非人类的访问模式应对方法:降低爬取频率,模拟人类浏览节奏使用代理IP池,定期切换IP随机化请求间隔,避免规律性分布式爬虫,分散请求压力JavaScript混淆网站使用JavaScript混淆技术保护数据:动态渲染:数据通过JS动态加载代码混淆:使代码难以理解和分析数据加密:对关键数据进行加密应对方法:使用浏览器自动化工具(Selenium)执行JS分析网络请求找到数据API逆向分析JS代码理解加密算法使用专业工具(如PyExecJS)执行关键JS代码请求头检测网站通过检查HTTP请求头识别爬虫:User-Agent检测:识别非浏览器UAReferer检查:验证请求来源Cookie验证:要求有效的会话CookieHeaders一致性:检查请求头组合是否合理应对方法:使用真实浏览器的User-Agent维护完整的请求头信息保持Cookie会话一致性爬虫代理和限速代理IP使用策略代理IP是绕过网站IP封禁的有效手段。根据不同需求可以选择不同类型的代理:透明代理目标网站能够检测到你在使用代理,并能够知道你的真实IP地址。这类代理主要用于匿名浏览,不适合爬虫使用。匿名代理目标网站能够检测到你在使用代理,但无法获知你的真实IP地址。提供基本的匿名性,但一些网站会直接拒绝代理IP访问。高匿代理目标网站无法检测你在使用代理,这类代理最适合爬虫使用。可以有效规避IP封禁,但价格较高且稳定性需要评估。住宅IP代理使用真实用户的住宅宽带IP作为代理,几乎不会被网站识别为代理IP。这是最高级的代理类型,价格也最昂贵。代理池构建importrequestsimportrandomimporttimefromconcurrent.futuresimportThreadPoolExecutorclassProxyPool:def__init__(self):xies=[]self.valid_proxies=[]defadd_proxies(self,proxy_list):xies.extend(proxy_list)defvalidate_proxy(self,proxy):try:response=requests.get('',proxies={'http':proxy,'https':proxy},timeout=5)ifresponse.status_code==200:print(f"代理{proxy}有效")returnproxyexcept:passreturnNonedefbuild_valid_pool(self):withThreadPoolExecutor(max_workers=10)asexecutor:results=list(executor.map(self.validate_proxy,xies))self.valid_proxies=[pforpinresultsifp]print(f"有效代理数量:{len(self.valid_proxies)}")defget_random_proxy(self):ifnotself.valid_proxies:returnNonereturnrandom.choice(self.valid_proxies)随机UA池构建classUserAgentPool:def__init__(self):self.user_agents=['Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/91.0.4472.124Safari/537.36','Mozilla/5.0(X11;Linuxx86_64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/92.0.4515.107Safari/537.36','Mozilla/5.0(WindowsNT10.0;Win64;x64;rv:90.0)Gecko/20100101Firefox/90.0','Mozilla/5.0(Macintosh;IntelMacOSX10_15_7)AppleWebKit/605.1.15(KHTML,likeGecko)Version/14.1.1Safari/605.1.15','Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/91.0.4472.124Safari/537.36Edg/91.0.864.59']defget_random_ua(self):returnrandom.choice(self.user_agents)限速与请求控制classRateLimiter:def__init__(self,max_requests=10,time_period=60):#最大请求数/时间周期(秒)self.max_requests=max_requestsself.time_period=time_periodself.request_timestamps=[]defwait_if_needed(self):"""如果请求过快,等待一段时间"""current_time=time.time()#移除过期的时间戳self.request_timestamps=[tsfortsinself.request_timestampsifcurrent_time-ts<self.time_period]#如果已达到限制,等待iflen(self.request_timestamps)>=self.max_requests:oldest_timestamp=min(self.request_timestamps)sleep_time=self.time_period-(current_time-oldest_timestamp)ifsleep_time>0:print(f"限速,等待{sleep_time:.2f}秒")time.sleep(sleep_time)#添加当前请求的时间戳self.request_timestamps.append(time.time())defrandom_delay(self,min_delay=1,max_delay=5):"""随机延迟,模拟人类行为"""delay=random.uniform(min_delay,max_delay)time.sleep(delay)分布式爬虫调度对于大规模爬虫项目,可以使用分布式架构分散请求压力:使用消息队列(如Redis、RabbitMQ)分发任务多台服务器部署爬虫,每台负责不同任务中央调度服务监控每台爬虫的状态和速率抓包与接口识别抓包工具的应用抓包工具是发现网站数据接口的利器,常用工具包括:Fiddler:Windows平台流行的抓包工具Charles:跨平台图形界面抓包工具Wireshark:功能强大的网络分析工具mitmproxy:命令行抓包工具,支持Python扩展使用抓包工具的主要步骤:安装并配置抓包工具(如安装证书)设置代理,让浏览器流量通过抓包工具访问目标网站,执行相关操作分析捕获的请求和响应筛选出包含目标数据的请求浏览器开发者工具分析浏览器自带的开发者工具也是非常强大的分析工具:打开浏览器开发者工具(F12或右键-检查)切换到Network面板访问目标页面并观察网络请求寻找包含所需数据的XHR/Fetch请求分析请求参数和响应数据格式分析技巧:使用Filter过滤器只显示XHR/Fetch请求通过请求名称或响应内容搜索相关数据分析请求头和参数,了解认证方式检查cookies和localStorage,发现关键信息接口还原与模拟综合案例1:电商商品价格监控项目目标开发一个爬虫系统,定期监控电商平台(如京东、淘宝)上特定商品的价格变化和评论,帮助用户获取价格走势和消费者反馈。技术栈选择Selenium:处理JavaScript渲染的动态页面BeautifulSoup:解析HTML提取数据SQLite:存储历史价格数据Matplotlib:生成价格走势图APScheduler:定时执行爬虫任务核心代码:商品页面爬取fromseleniumimportwebdriverfromselenium.webdriver.chrome.serviceimportServicefrommon.byimportByfrombs4importBeautifulSoupimporttimeimportsqlite3importdatetimedefget_jd_product_info(product_id):service=Service('path/to/chromedriver')driver=webdriver.Chrome(service=service)url=f"/{product_id}.html"try:driver.get(url)time.sleep(2)#等待页面加载#获取商品标题title=driver.find_element(By.CLASS_NAME,'sku-name').text.strip()#获取商品价格price_element=driver.find_element(By.CLASS_NAME,'price')price=price_element.text.replace('¥','').strip()#获取评论数量driver.get(f"/{product_id}.html#comment")time.sleep(2)#等待评论加载comment_count=driver.find_element(By.CLASS_NAME,'count').text.strip()return{'id':product_id,'title':title,'price':float(price),'comment_count':comment_count,'date':datetime.datetime.now().strftime('%Y-%m-%d%H:%M:%S')}finally:driver.quit()多页面遍历与存储defsave_product_info(product_info):conn=sqlite3.connect('jd_products.db')cursor=conn.cursor()#创建表(如果不存在)cursor.execute('''CREATETABLEIFNOTEXISTSproducts(idINTEGER,titleTEXT,priceREAL,comment_countTEXT,dateTEXT,PRIMARYKEY(id,date))''')#插入数据cursor.execute('''INSERTINTOproducts(id,title,price,comment_count,date)VALUES(?,?,?,?,?)''',(product_info['id'],product_info['title'],product_info['price'],product_info['comment_count'],product_info['date']))mit()conn.close()#批量处理多个商品defmonitor_products(product_ids):forproduct_idinproduct_ids:try:product_info=get_jd_product_info(product_id)save_product_info(product_info)print(f"商品{product_id}信息保存成功")exceptExceptionase:print(f"处理商品{product_id}时出错:{e}")#间隔一段时间再请求下一个商品time.sleep(10)#设置定时任务fromapscheduler.schedulers.blockingimportBlockingSchedulerscheduler=BlockingScheduler()product_ids=['100012345678','100023456789','100034567890']#每天早上10点和晚上8点执行scheduler.add_job(lambda:monitor_products(product_ids),'cron',hour='10,20',id='monitor_job')print("价格监控任务已启动...")scheduler.start()综合案例2:招聘信息爬取1需求分析开发一个爬虫,从智联招聘、拉勾网等招聘平台抓取特定职位的招聘信息,包括:职位名称、公司名称工作地点、薪资范围职位要求、工作职责公司规模、行业、融资状况支持按城市、职位类型、薪资范围等条件筛选,帮助求职者快速找到合适岗位,或者帮助HR了解市场行情。2爬虫实现importrequestsfrombs4importBeautifulSoupimportpandasaspdimporttimeimportrandomfromfake_useragentimportUserAgentclassLagouJobSpider:def__init__(self):self.ua=UserAgent()self.base_url="/wn/jobs"=[]defget_job_list(self,keyword,city,page=1):"""获取职位列表页"""params={'kd':keyword,'city':city,'pn':page}headers={'User-Agent':self.ua.random,'Referer':'','Accept':'application/json,text/javascript,*/*;q=0.01','X-Requested-With':'XMLHttpRequest'}#拉勾网有反爬措施,这里简化处理#实际中需要处理Cookies和请求顺序try:response=requests.get(self.base_url,params=params,headers=headers,timeout=10)soup=BeautifulSoup(response.text,'html.parser')job_items=soup.select('.item__10RTO')foriteminjob_items:job_info={}job_info['title']=item.select_one('.p-top__1F7CLa').text.strip()job_info['company']=item.select_one('.company-name__2-SjFa').text.strip()job_info['location']=item.select_one('.p-top__1F7CLspan').text.strip()job_info['salary']=item.select_one('.money__3Lkgq').text.strip()job_info['experience']=item.select_one('.li__l7JMI:nth-child(1)').text.strip()job_info['education']=item.select_one('.li__l7JMI:nth-child(2)').text.strip()job_info['company_type']=item.select_one('.industry__1HBkr').text.strip()job_url=item.select_one('.p-top__1F7CLa')['href']job_info['url']=job_url.append(job_info)returnlen(job_items)>0exceptExceptionase:print(f"获取职位列表出错:{e}")returnFalse数据存储与更新defget_job_details(self,job_info):"""获取职位详情页"""headers={'User-Agent':self.ua.random,'Referer':self.base_url}try:response=requests.get(job_info['url'],headers=headers,timeout=10)soup=BeautifulSoup(response.text,'html.parser')#提取职位描述description=soup.select_one('.job-detail')ifdescription:job_info['description']=description.text.strip()#提取公司信息company_info=soup.select_one('.company-info__3Z4CY')ifcompany_info:job_info['company_size']=company_info.select_one('li:nth-child(3)').text.strip()job_info['company_status']=company_info.select_one('li:nth-child(2)').text.strip()returnjob_infoexceptExceptionase:print(f"获取职位详情出错:{e}")returnjob_infodefsave_to_csv(self,filename='lagou_jobs.csv'):"""保存数据到CSV文件"""ifnot:print("没有职位数据可保存")returndf=pd.DataFrame()df.to_csv(filename,index=False,encoding='utf-8-sig')print(f"已保存{len()}条职位信息到{filename}")defrun(self,keyword,city,max_pages=5):"""运行爬虫"""print(f"开始爬取{city}地区的{keyword}职位...")forpageinrange(1,max_pages+1):print(f"正在爬取第{page}页...")ifnotself.get_job_list(keyword,city,page):print(f"没有更多数据,爬取结束于第{page}页")break#随机延迟time.sleep(random.uniform(3,5))print("开始获取职位详情...")fori,jobinenumerate():print(f"正在获取第{i+1}/{len()}个职位详情")[i]=self.get_job_details(job)time.sleep(random.uniform(2,4))self.save_to_csv()print("爬取完成!")#使用示例if__name__=="__main__":spider=LagouJobSpider()spider.run(keyword="Python开发",city="北京",max_pages=3)4定时更新机制由于招聘信息经常更新,需要建立定时更新机制:综合案例3:学术文献批量采集项目背景为学术研究者开发一个批量下载学术文献的爬虫工具,支持从CNKI、万方、谷歌学术等平台搜索并下载相关论文。这类爬虫需要解决的主要挑战:学术网站反爬措施普遍严格大多需要登录或验证码识别下载限制与IP封禁频繁文件格式多样,需处理PDF、CAJ等CNKI爬虫实现fromseleniumimportwebdriverfromselenium.webdriver.chrome.serviceimportServicefrommon.byimportByfromselenium.webdriver.support.uiimportWebDriverWaitfromselenium.webdriver.supportimportexpected_conditionsasECimporttimeimportosimportrandomimportddddocr#验证码识别库classCNKISpider:def__init__(self,username,password):self.username=usernameself.password=passwordservice=Service('/path/to/chromedriver')options=webdriver.ChromeOptions()#设置下载路径prefs={"download.default_directory":os.path.join(os.getcwd(),"papers"),"mpt_for_download":False}options.add_experimental_option("prefs",prefs)self.driver=webdriver.Chrome(service=service,options=options)self.wait=WebDriverWait(self.driver,20)#创建下载目录os.makedirs("papers",exist_ok=True)deflogin(self):"""登录CNKI"""self.driver.get("/kns8/AdvSearch")#点击登录按钮login_btn=self.wait.until(EC.element_to_be_clickable((By.XPATH,"//a[contains(text(),'登录')]")))login_btn.click()#切换到登录框架self.wait.until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[@id='loginIframe']")))#输入用户名密码self.wait.until(EC.element_to_be_clickable((By.ID,"TextBoxUserName"))).send_keys(self.username)self.driver.find_element(By.ID,"TextBoxPassword").send_keys(self.password)#处理验证码ifself.is_captcha_present():self.solve_captcha()#点击登录self.driver.find_element(By.ID,"Button1").click()#等待登录成功time.sleep(3)#切回主框架self.driver.switch_to.default_content()print("登录成功!")验证码处理与文件下载defis_captcha_present(self):"""检查是否存在验证码"""try:captcha_img=self.driver.find_element(By.ID,"checkcode")returncaptcha_img.is_displayed()except:returnFalsedefsolve_captcha(self):"""处理验证码"""try:#截取验证码图片captcha_img=self.driver.find_element(By.ID,"checkcode")captcha_img.screenshot("captcha.png")#使用OCR识别验证码ocr=ddddocr.DdddOcr()withopen("captcha.png","rb")asf:img_bytes=f.read()captcha_text=ocr.classification(img_bytes)#输入验证码self.driver.find_element(By.ID,"TextBoxVerifyCode").send_keys(captcha_text)print(f"验证码
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026云南西双版纳州勐腊县紧密型县域医共体招聘16人备考题库及答案详解参考
- 2026贵州六盘水盘州市盘医后勤服务有限责任公司污水处理站工作人员招聘2人备考题库有答案详解
- 2026年天门市人才引进63人备考题库附答案详解(巩固)
- 2026广东清远市连山县上帅镇招聘村委会计生指导员2人备考题库附答案详解(培优a卷)
- 2025年脑机接口驱动的肘关节功能康复训练
- 2026贵州贵阳贵安公安机关面向社会招聘警务辅助人员333人备考题库含答案详解(典型题)
- 2026年衢州市江山市体育馆公开招聘体育教练员1人备考题库及答案详解(基础+提升)
- 2026鹤壁入团考试题及答案解析
- 幼儿园运动会运动员代表发言
- 2026山东日照农发集团招聘10人备考题库及答案详解参考
- 四议两公开培训会
- 血脂知识科普课件
- 肺部磁共振成像在肺疾病诊断中的价值
- 初中八年级数学课件-一次函数的图象与性质【全国一等奖】
- 《石墨类负极材料检测方法 第1部分:石墨化度的测定》
- 贵州艺辰纸业有限责任公司年产15万吨化学机械木浆的林纸一体化生产线及配套的纸板生产线(一期)环评报告
- 鳞翅目检疫性害虫课件
- 硬笔书法 撇和捺的写法课件
- JJG 444-2023标准轨道衡
- GB/T 15530.6-2008铜管折边和铜合金对焊环松套钢法兰
- GRR培训-完整版课件
评论
0/150
提交评论