用scrapy进行网页抓取

不问归期 提交于 2019-12-08 22:24:18

最近用scrapy来进行网页抓取,对于pythoner来说它用起来非常方便,详细文档在这里:http://doc.scrapy.org/en/0.14/index.html

要想利用scrapy来抓取网页信息,需要先新建一个工程,scrapy startproject myproject

工程建立好后,会有一个myproject/myproject的子目录,里面有item.py(由于你要抓取的东西的定义),pipeline.py(用于处理抓取后的数据,可以保存数据库,或是其他),然后是spiders文件夹,可以在里面编写爬虫的脚本.

这里以爬取某网站的书籍信息为例:

item.py如下:

?

[python] view plaincopy
  1. from scrapy.item import Item, Field  
  2.   
  3. class BookItem(Item):  
  4.     # define the fields for your item here like:  
  5.     name = Field()  
  6.     publisher = Field()  
  7.     publish_date = Field()  
  8.     price = Field()  

?

我们要抓取的东西都在上面定义好了,分别是名字,出版商,出版日期,价格,

下面就要写爬虫去网战抓取信息了,

spiders/book.py如下:

?

[python] view plaincopy
  1. from urlparse import urljoin  
  2. import simplejson  
  3.   
  4. from scrapy.http import Request  
  5. from scrapy.contrib.spiders import CrawlSpider, Rule  
  6. from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor  
  7. from scrapy.selector import HtmlXPathSelector  
  8.   
  9. from myproject.items import BookItem  
  10.   
  11. class BookSpider(CrawlSpider):  
  12.     name = 'bookspider'  
  13.     allowed_domains = ['test.com']  
  14.     start_urls = [  
  15.         "http://test_url.com",   #这里写开始抓取的页面地址(这里网址是虚构的,实际使用时请替换)  
  16.     ]  
  17.     rules = (  
  18.         #下面是符合规则的网址,但是不抓取内容,只是提取该页的链接(这里网址是虚构的,实际使用时请替换)  
  19.         Rule(SgmlLinkExtractor(allow=(r'http://test_url/test?page_index=\d+'))),  
  20.         #下面是符合规则的网址,提取内容,(这里网址是虚构的,实际使用时请替换)  
  21.         Rule(SgmlLinkExtractor(allow=(r'http://test_rul/test?product_id=\d+')), callback="parse_item"),  
  22.     )  
  23.   
  24.           
  25.     def parse_item(self, response):  
  26.         hxs = HtmlXPathSelector(response)  
  27.         item = BookItem()  
  28.         item['name'] = hxs.select('//div[@class="h1_title book_head"]/h1/text()').extract()[0]  
  29.         item['author'] = hxs.select('//div[@class="book_detailed"]/p[1]/a/text()').extract()  
  30.         publisher = hxs.select('//div[@class="book_detailed"]/p[2]/a/text()').extract()  
  31.         item['publisher'] = publisher and publisher[0or ''  
  32.         publish_date = hxs.select('//div[@class="book_detailed"]/p[3]/text()').re(u"[\u2e80-\u9fffh]+\uff1a([\d-]+)")  
  33.         item['publish_date'] = publish_date and publish_date[0or ''  
  34.         prices = hxs.select('//p[@class="price_m"]/text()').re("(\d*\.*\d*)")  
  35.         item['price'] = prices and prices[0or ''  
  36.         return item  

然后信息抓取后,需要保存,这时就需要写pipelines.py了(用于scapy是用的twisted,所以具体的数据库操作可以看twisted的资料,这里只是简单介绍如何保存到数据库中):

?

[python] view plaincopy
  1. from scrapy import log  
  2. #from scrapy.core.exceptions import DropItem  
  3. from twisted.enterprise import adbapi  
  4. from scrapy.http import Request  
  5. from scrapy.exceptions import DropItem  
  6. from scrapy.contrib.pipeline.images import ImagesPipeline  
  7. import time  
  8. import MySQLdb  
  9. import MySQLdb.cursors  
  10.   
  11.   
  12. class MySQLStorePipeline(object):  
  13.   
  14.     def __init__(self):  
  15.         self.dbpool = adbapi.ConnectionPool('MySQLdb',  
  16.                 db = 'test',  
  17.                 user = 'user',  
  18.                 passwd = '******',  
  19.                 cursorclass = MySQLdb.cursors.DictCursor,  
  20.                 charset = 'utf8',  
  21.                 use_unicode = False  
  22.         )  
  23.   
  24.     def process_item(self, item, spider):  
  25.           
  26.         query = self.dbpool.runInteraction(self._conditional_insert, item)  
  27.           
  28.         query.addErrback(self.handle_error)  
  29.         return item  
  30.     
  31.     def _conditional_insert(self, tx, item):  
  32.         if item.get('name'):  
  33.             tx.execute(\  
  34.                 "insert into book (name, publisher, publish_date, price ) \  
  35.                  values (%s, %s, %s, %s)",  
  36.                 (item['name'],  item['publisher'], item['publish_date'],   
  37.                 item['price'])  
  38.             )  
?

完成之后在setting.py中添加该pipeline:

?

[python] view plaincopy
  1. ITEM_PIPELINES = ['myproject.pipelines.MySQLStorePipeline']  

?最后运行scrapy crawl bookspider就开始抓取了

?

本文地址http://www.chengxuyuans.com/Python/39302.html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!