根据架构图介绍一下Scrapy中的各大组件及其功能:
Scrapy引擎(Engine):负责控制数据流在系统的所有组建中流动,并在相应动作发生触发事件。
调度器(Scheduler):从引擎接收Request并将它们入队,以便之后引擎请求request时提供给引擎。
下载器(Downloader):负责获取页面数据并提供给引擎,而后提供给Spider。
Spider:Scrapy用户编写用于分析Response并提取Item(即获取到的Item)或额外跟进的URL的类。每个Spider负责处理一个特定(或一些网站)。
Item Pipeline:负责处理被Spider提取出来的Item。典型的处理有清理验证及持久化(例如存储到数据库中,这部分后面会介绍存储到MySQL中,其他的数据库类似)。
下载器中间件(Downloader middlewares):是在引擎即下载器之间的特定钩子(special hook),处理Downloader传递给引擎的Response。其提供了一个简便的机制,通过插入自定义代码来扩展Scrapy功能(后面会介绍配置一些中间并激活,用以应对反爬虫)。
Spider中间件(Spider middlewares):是在引擎及Spider之间的特定钩子(special hook),处理Spider的输入(response)和输出(Items即Requests)。其提供了一个简便的机制,通过插入自定义的代码来扩展Scrapy功能。
(1)一种是像我之前爬虫新京报网的新闻,下一页的url可以通过审查元素获得,第一页的网址是http://www.bjnews.com.cn/news/list-43-page-1.html在第一页的时候,下一页按钮的审查元素是
我们通过获取next_pages = response.xpath('//div[@id="page"]/a[@class="next"]/@href').extract()[0]
,便可以得到下一页的url,next_page = "http://www.bjnews.com.cn" + next_pages,
这一部分的完整代码为:
page_link=set() #保存下一页页面url
content_link=set() #保存页面内所有可获得的url
rules={'page':LinkExtractor(allow=(r'^http://www.bjnews.com.cn/\w+/2016/\d{2}/\d{2}/\d{6}.html
))}
start_urls={'http://www.bjnews.com.cn/news/list-43-page-1.html'}
def parse(self, response):
#爬取一个页面内的所有url链接
for link in self.rules['page'].extract_links(response):
if link.url not in self.content_link:
self.page_link.add(link.url)
yield scrapy.Request(link.url, callback=self.parse_item)
#自动获取下一页的url
next_pages = response.xpath('//div[@id="page"]/a[@class="next"]/@href').extract()[0]
if next_pages:
next_page = "http://www.bjnews.com.cn" + next_pages
self.page_link.add(next_page)
yield scrapy.Request(next_page, callback=self.parse)
(2)第二种情况,就是在下一页的审查元素中没有提供url链接,需要自己分析,在这里依然举个例子,比如搜狐新闻http://news.sohu.com/guojixinwen.shtml,该页中下一页按钮的审查元素是:
我们不能通过href来直接过得下一页的url,需要自己手动获得,那现在我们来分析
第二页的url:http://news.sohu.com/guojixinwen_5230.shtml,第三页的http://news.sohu.com/guojixinwen_5229.shtml,最后一页的http://news.sohu.com/guojixinwen_5132.shtml,由此可以分析出这一共100页的url,是http://news.sohu.com/guoneixinwen_"+i+".shtml",其中i是从5230到5132倒序排列的,也就是说通过for循环,就可以获得这100页的所有url,完整代码如下:在这里给大家加一个新的方法的使用start_request,该方法就是子定义start_urls,把所有自定义的url放到page_link中,self.make_requests_from_url方法会自动获取里面的请求
不同模式不同方法,就讲解下你这个文本格式吧。文本格式,首先 BeautifulSoup(文本),类型修改
然后 文本.findAll() 找出所有
遍历数组,打印 .contents
判断数组len(i.contents) 为1的取出(道理就不说了),自己去尝试下,如果基础不差的话,应该可以看到结果。