py spider 第一天

总结: selenium只是个虚拟的浏览器,或者说是一个web自动化测试工具,而不是真正意义上的爬虫框架

一、Scrapy

Scrapy A Fast and Powerful Scraping and Web Crawling Framework

关键词是和,使用过确实感觉如此。我感觉就是一个全家桶,它把爬虫所需要的大部分东西(为什么不是全部,下面会说到)都集成到这个框架中,如:下载器、中间件、调度器、Spider、调试、数据流等等所有功能全部都在这一个框架中,你所需要做的只是在命令行中输入:

Scrapy 的缺点也是显而易见的:不支持分布式。scrapy中scheduler是运行在队列中的,而队列是在单机内存中的,服务器上爬虫是无法利用内存的队列做任何处理。但是也有解决办法,参见rmax/scrapy-redis

二、selenium

selenium :最后来到今天的主角Selenium, 首先看看官方怎么说

What is Selenium?

Selenium automates browsers. That’s it! What you do with that power is entirely up to you. Primarily, it is for automating web applications for testing purposes, but is certainly not limited to just that. Boring web-based administration tasks can (and should!) be automated as well.

Selenium has the support of some of the largest browser vendors who have taken (or are taking) steps to make Selenium a native part of their browser. It is also the core technology in countless other browser automation tools, APIs and frameworks.

重点是:,翻译过来就是:它是用于自动化Web应用程序的测试目的,但肯定不仅限于此,简单来说,Selenium 是web自动化测试工具集,如果你去Google上搜索 Selenium ,大多结果都是相关内容,比较出名的有博客园的虫师,写的两本书也都是关于自动化测试方面的

至于为啥爬虫要用selenium,我在某些博客上找到有人这样说,我也不知道怎么说

对于一般网站来说scrapy、requests、beautifulsoup等都可以爬取,但是有些信息需要执行js才能显现,而且你肉眼所能看到的基本都能爬取下来,在学习中遇到了,就记录下来方便以后查看。

webdrive是selenium中一个函数:

from selenium import webdriver

driver = webdriver.Chrome()

driver.get(‘网址’)

其中PhantomJS同时可以换成Chrome、Firefox、Ie等等,但是PhantomJS是一个无头的浏览器,运行是不会跳出相应的浏览器,运行相对效率较高。在调试中可以先换成Chrome,方便调试,最后再换成PhantomJS即可。

下面是吐槽时间,说一说的缺点:

速度慢。每次运行爬虫都打开一个浏览器,如果没有设置,还会加载图片、JS等等一大堆东西;

占用资源太多。有人说,把换成无头浏览器,原理都是一样的,都是打开浏览器,而且很多网站会验证参数,如果对方看到你是以去访问,会BAN掉你的请求,然后你又要考虑更换请求头的事情,事情复杂程度不知道多了多少,为啥学Python?因为Python简单啊,如果有更快、更简单的库可以实现同样的功能,为什么不去使用呢?

对网络的要求会更高。加载了很多可能对您没有价值的补充文件(如css,js和图像文件)。 与仅仅请求您真正需要的资源(使用单独的HTTP请求)相比,这可能会产生更多的流量。

**

BeautifulSoup

BeautifulSoup是一个模块,该模块用于接收一个HTML或XML字符串,然后将其进行格式化,之后就可以使用他提供的方法进行快速查找指定元素,从而使得在HTML或XML中查找指定元素变得简单。

四大对象种类:
Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:

Tag:HTML 中的一个个标签,比如a,div等,有两个属性name和attrs

NavigableString:标签内部的文字,可以用 .string获得

BeautifulSoup:表示的是一个文档的全部内容

Comment:注释
<think>我们使用Scrapy框架来爬取指定网页的新闻数据(包括图片、标题和时间),并将数据保存为CSV和Excel文件。步骤:1.创建Scrapy项目2.定义Item3.编写Spider4.编写Pipeline来处理数据的存储(包括CSV和Excel)5.配置settings.py启用Pipeline由于需要保存为两种格式(CSV和Excel),我们可以使用两个Pipeline,或者在一个Pipeline中同时保存两种格式。这里为了清晰,我们使用两个Pipeline,分别处理CSV和Excel。另外,新闻图片需要下载,我们将使用Scrapy的ImagesPipeline来下载图片,同时我们自定义的Pipeline将处理CSV和Excel的保存。因此,我们需要:-一个ImagesPipeline用于下载图片-一个自定义Pipeline用于保存CSV-另一个自定义Pipeline用于保存Excel但注意:Scrapy的ItemPipeline是顺序执行的,我们可以配置多个Pipeline。具体步骤:一、创建项目在命令行中执行:scrapystartprojectinspur_newscdinspur_news二、定义Item在items.py中定义我们要爬取的字段:title:新闻标题time:新闻时间image_urls:图片的URL(用于下载图片,注意字段名必须是image_urls,因为ImagesPipeline会使用这个字段)images:图片下载后的信息(ImagesPipeline会自动填充)三、创建Spider使用命令创建Spiderscrapygenspidernewscloud.inspur.com然后修改news.py,编写解析函数。四、编写ImagesPipeline在settings.py中启用并配置ImagesPipeline,并设置存储路径。五、编写两个自定义Pipeline:一个用于保存CSV,一个用于保存Excel。六、在settings.py中启用我们自定义的Pipeline。下面详细说明:1.定义Item(items.py):```pythonimportscrapyclassInspurNewsItem(scrapy.Item):title=scrapy.Field()time=scrapy.Field()image_urls=scrapy.Field()#图片的URL列表images=scrapy.Field()#图片下载后的信息(由ImagesPipeline填充)```2.编写Spider(news.py):我们需要解析https://cloud.inspur.com/about-inspurcloud/about-us/news/index.html页面。观察页面结构,新闻列表在class="news-list"的ul中,每个新闻条目是li。每个li中包含图片(在divclass="img"下)、标题(在divclass="news-info"下的h3)和时间(在divclass="news-info"下的pclass="date")。注意:图片的URL可能是相对路径,需要转换为绝对路径。Spider代码示例:```pythonimportscrapyfrominspur_news.itemsimportInspurNewsItemfromurllib.parseimporturljoinclassNewsSpider(scrapy.Spider):name='news'allowed_domains=['cloud.inspur.com']start_urls=['https://cloud.inspur.com/about-inspurcloud/about-us/news/index.html']defparse(self,response):#获取新闻列表news_list=response.css('ul.news-listli')fornewsinnews_list:item=InspurNewsItem()#标题title=news.css('div.news-infoh3::text').get()#时间time=news.css('div.news-infop.date::text').get()#图片URL(注意是相对路径,需要拼接)image_relative_url=news.css('div.imgimg::attr(src)').get()image_url=urljoin(response.url,image_relative_url)item['title']=title.strip()iftitleelseNoneitem['time']=time.strip()iftimeelseNoneitem['image_urls']=[image_url]#注意:image_urls需要是列表yielditem```3.配置ImagesPipeline(settings.py):在settings.py中添加以下配置:```python#启用ImagesPipelineITEM_PIPELINES={'scrapy.pipelines.images.ImagesPipeline':1,#图片管道#我们自定义的管道将在后面添加}#图片存储路径IMAGES_STORE='images'#图片将下载到项目目录下的images文件夹中#可选:设置图片下载的过期时间等#IMAGES_EXPIRES=30#30天内不会重复下载```注意:ImagesPipeline默认会使用我们定义的`image_urls`字段来下载图片,并将结果填充到`images`字段。`images`字段将包含一个列表,每个元素是一个字典,包括下载路径、URL、校验和等。4.编写自定义Pipeline用于保存CSV和Excel:我们需要两个Pipeline,分别保存为CSV和Excel。首先,在项目目录下创建一个pipelines.py文件(如果不存在则创建),然后编写两个类:(1)保存CSV的Pipeline:```pythonimportcsvfromitemadapterimportItemAdapterclassCsvPipeline:defopen_spider(self,spider):#在爬虫开始时打开文件self.file=open('data.csv','w',encoding='utf-8',newline='')#定义CSV列名self.fieldnames=['title','time','image_path']self.writer=csv.DictWriter(self.file,fieldnames=self.fieldnames)self.writer.writeheader()defclose_spider(self,spider):#在爬虫结束时关闭文件self.file.close()defprocess_item(self,item,spider):#处理每个item,写入CSV#注意:item['images']是一个列表,我们取第一个图片的路径(如果有多个图片,这里只取第一个)image_path=item['images'][0]['path']ifitem['images']elseNone#构造一行数据row={'title':item['title'],'time':item['time'],'image_path':image_path}self.writer.writerow(row)returnitem```(2)保存Excel的Pipeline:我们需要安装openpyxl库:`pipinstallopenpyxl````pythonimportopenpyxlfromitemadapterimportItemAdapterclassExcelPipeline:defopen_spider(self,spider):#创建一个工作簿和工作表self.wb=openpyxl.Workbook()self.ws=self.wb.activeself.ws.title='新闻'#写入表头self.ws.append(['标题','时间','图片路径'])defclose_spider(self,spider):#保存文件self.wb.save('xinwen.xlsx')defprocess_item(self,item,spider):#处理每个item,写入Excelimage_path=item['images'][0]['path']ifitem['images']elseNoneself.ws.append([item['title'],item['time'],image_path])returnitem```5.在settings.py中启用这两个自定义Pipeline,并设置优先级(注意优先级数字越小越先执行,但ImagesPipeline应该先执行,因为它要下载图片,然后我们才能得到图片路径):```pythonITEM_PIPELINES={'scrapy.pipelines.images.ImagesPipeline':1,#图片管道,优先级最高'inspur_news.pipelines.CsvPipeline':2,#CSV管道'inspur_news.pipelines.ExcelPipeline':3,#Excel管道}```注意:上面的Pipeline类放在pipelines.py文件中,并且需要确保在settings.py中正确指定了路径(即'inspur_news.pipelines.CsvPipeline',其中'inspur_news'是项目名)。6.运行爬虫:在命令行中执行:scrapycrawlnews问题与优化:-上面的代码中,我们假设每个新闻条目只有一张图片。如果有多张,需要调整。-我们只爬取了第一页,如果有多页,需要在Spider中实现翻页。翻页实现:观察页面,底部有分页,我们可以提取下一页的链接并递归请求。在parse方法中,可以添加:next_page=response.css('div.pagea.next::attr(href)').get()ifnext_page:next_url=urljoin(response.url,next_page)yieldscrapy.Request(next_url,callback=self.parse)修改后的Spider(news.py):```pythonimportscrapyfrominspur_news.itemsimportInspurNewsItemfromurllib.parseimporturljoinclassNewsSpider(scrapy.Spider):name='news'allowed_domains=['cloud.inspur.com']start_urls=['https://cloud.inspur.com/about-inspurcloud/about-us/news/index.html']defparse(self,response):#获取新闻列表news_list=response.css('ul.news-listli')fornewsinnews_list:item=InspurNewsItem()#标题title=news.css('div.news-infoh3::text').get()#时间time=news.css('div.news-infop.date::text').get()#图片URL(注意是相对路径,需要拼接)image_relative_url=news.css('div.imgimg::attr(src)').get()image_url=urljoin(response.url,image_relative_url)item['title']=title.strip()iftitleelseNoneitem['time']=time.strip()iftimeelseNoneitem['image_urls']=[image_url]#注意:image_urls需要是列表yielditem#翻页next_page=response.css('div.pagea.next::attr(href)').get()ifnext_page:next_url=urljoin(response.url,next_page)yieldscrapy.Request(next_url,callback=self.parse)```注意:在保存Excel时,如果数据量很大,可能会占用较多内存。可以考虑分批写入。另外,在Pipeline中,我们只保存了图片的路径(相对路径,相对于IMAGES_STORE)。如果需要,也可以保存图片的URL或者其他信息。以上代码仅供参考,实际运行时可能需要根据网页结构调整选择器。最后,确保在settings.py中设置了ROBOTSTXT_OBEY=False(因为默认是True,可能会遵守robots.txt而无法爬取)。运行爬虫后,将得到:-图片下载到images目录下-数据保存到data.csv和xinwen.xlsx文件中如果遇到403错误,可能需要设置User-Agent等,可以在settings.py中设置USER_AGENT。设置USER_AGENT(例如):USER_AGENT='Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/58.0.3029.110Safari/537.36'如果网站有反爬措施,可能需要进一步处理。根据引用[5]中的日志,有时会返回403,因此我们可以在请求头中设置User-Agent来避免。在Spider中设置start_requests方法,自定义请求头:```pythonclassNewsSpider(scrapy.Spider):#...其他代码defstart_requests(self):headers={'User-Agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/58.0.3029.110Safari/537.36'}forurlinself.start_urls:yieldscrapy.Request(url,headers=headers,callback=self.parse)```或者在settings.py中设置全局的USER_AGENT。至此,我们完成了爬取任务。注意:由于网站可能会更新,选择器可能需要调整,请根据实际情况修改。相关问题:1.如何避免Scrapy爬虫被网站屏蔽?2.如何提高Scrapy爬虫的下载速度?3.在Scrapy中如何处理动态加载的网页(如JavaScript渲染的内容)?4.如何将Scrapy爬取的数据存储到数据库中(如MySQL、MongoDB)?</think>### 使用Scrapy爬取浪潮云新闻数据并保存为CSV/Excel #### 一、实现步骤 1. **创建Scrapy项目** ```bash scrapy startproject inspur_news cd inspur_news scrapy genspider news cloud.inspur.com ``` 2. **定义Item字段(items.py)** ```python import scrapy class InspurNewsItem(scrapy.Item): title = scrapy.Field() # 新闻标题 time = scrapy.Field() # 发布时间 image_url = scrapy.Field() # 图片URL image_path = scrapy.Field() # 图片本地路径 ``` 3. **编写爬虫逻辑(spiders/news.py)** ```python import scrapy from inspur_news.items import InspurNewsItem from urllib.parse import urljoin class NewsSpider(scrapy.Spider): name = 'news' start_urls = ['https://cloud.inspur.com/about-inspurcloud/about-us/news/index.html'] def parse(self, response): for article in response.css('ul.news-list li'): item = InspurNewsItem() # 提取标题 item['title'] = article.css('div.news-info h3::text').get().strip() # 提取时间 item['time'] = article.css('div.news-info p.date::text').get().strip() # 提取图片URL(处理相对路径) image_relative = article.css('div.img img::attr(src)').get() item['image_url'] = urljoin(response.url, image_relative) yield item ``` 4. **配置管道(pipelines.py)** ```python import csv import openpyxl from scrapy.pipelines.images import ImagesPipeline from itemadapter import ItemAdapter # 图片下载管道 class NewsImagesPipeline(ImagesPipeline): def get_media_requests(self, item, info): yield scrapy.Request(item['image_url'], meta={'item': item}) def file_path(self, request, response=None, info=None): item = request.meta['item'] return f'images/{item["title"]}.jpg' def item_completed(self, results, item, info): if results and results[0][0]: item['image_path'] = results[0][1]['path'] return item # CSV保存管道 class CsvPipeline: def open_spider(self, spider): self.file = open('data.csv', 'w', newline='', encoding='utf-8') self.writer = csv.writer(self.file) self.writer.writerow(['标题', '时间', '图片路径']) def close_spider(self, spider): self.file.close() def process_item(self, item, spider): self.writer.writerow([ item['title'], item['time'], item.get('image_path', '') ]) return item # Excel保存管道 class ExcelPipeline: def open_spider(self, spider): self.wb = openpyxl.Workbook() self.ws = self.wb.active self.ws.append(['标题', '时间', '图片路径']) def close_spider(self, spider): self.wb.save('xinwen.xlsx') def process_item(self, item, spider): self.ws.append([ item['title'], item['time'], item.get('image_path', '') ]) return item ``` 5. **启用管道(settings.py)** ```python ITEM_PIPELINES = { 'inspur_news.pipelines.NewsImagesPipeline': 300, # 图片下载 'inspur_news.pipelines.CsvPipeline': 400, # CSV保存 'inspur_news.pipelines.ExcelPipeline': 500, # Excel保存 } IMAGES_STORE = 'images' # 图片存储目录 FEED_EXPORT_ENCODING = 'utf-8-sig' # 解决CSV中文乱码 ROBOTSTXT_OBEY = False # 忽略robots.txt ``` 6. **运行爬虫** ```bash scrapy crawl news ``` #### 二、输出结果 1. **文件结构** ``` ├── data.csv # CSV格式数据 ├── xinwen.xlsx # Excel格式数据 └── images/ # 下载的新闻图片 ├── 新闻标题1.jpg ├── 新闻标题2.jpg ... ``` 2. **CSV示例内容** ``` 标题,时间,图片路径 "浪潮云通过可信云多项认证","2023-07-18","images/浪潮云通过可信云多项认证.jpg" "云洲操作系统通过等保2.0认证","2023-06-15","images/云洲操作系统通过等保2.0认证.jpg" ``` #### 三、注意事项 1. **反爬处理**:如遇403错误,需在`settings.py`中添加: ```python USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' DOWNLOAD_DELAY = 1 # 下载延迟 ``` 2. **数据清洗**:可在`pipelines.py`中添加清洗逻辑: ```python def clean_time(time_str): # 示例:将"2023年7月18日"转为"2023-07-18" return re.sub(r'(\d+)年(\d+)月(\d+)日', r'\1-\2-\3', time_str) ``` 3. **动态页面处理**:如果页面是JavaScript渲染,需改用`Splash`或`Selenium`[^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值