初学scrapy框架,很多地方一知半解,先跟着书上的代码一个字一个字敲,还有很多细节值得钻研
先来个简单的吧,新建一个scrapy项目xiaozhu
小猪短租信息爬取、不分页、不进入详细页面查找,输出形式为打印
只搜寻一个网页上的信息 http://bj.xiaozhu.com/search-duanzufang-p2-0/,字段为title(名称)、price(价格)、href(每个房源的详细页链接)
items.py 修改如下:
from scrapy import Item,Field class XiaozhuItem(Item): #define the fields for your item here like: title = Field() price = Field() href = Field() pass
settings.py 在默认上面添加了以下信息,其他不动
# Override the default request headers: DEFAULT_REQUEST_HEADERS = { "User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36", } # 配置使用Pipeline ITEM_PIPELINES = { 'xiaozhu.pipelines.XiaozhuPipeline': 300, }
最重要的就是自己写的爬虫规则文件xiaozhuspider.py了
1 from scrapy.spiders import CrawlSpider 2 from scrapy.selector import Selector 3 from xiaozhu.items import XiaozhuItem 4 5 class XiaozhuSpider(CrawlSpider): 6 # 定义该Spider的名字 7 name = 'xiaozhu' 8 # # 定义该Spider允许爬取的域名 9 #allowed_domains = ['xiaozhu.com'] 10 # 定义该Spider爬取的首页列表 11 start_urls = ['http://bj.xiaozhu.com/search-duanzufang-p2-0/'] 12 13 def parse(self, response): 14 #print(response,'\n') # 返回状态码 15 #print(response.text) 16 item = XiaozhuItem() 17 selector = Selector(response) 18 list = selector.xpath('//*[@id="page_list"]/ul/li') 19 #print(len(list),list) 20 for i in list: 21 #print(i) 22 item['title'] = i.xpath('div[2]/div[2]/a/span/text()').extract()[0] 23 item['price'] = i.xpath('div[2]/div[1]/span/i/text()').extract()[0] 24 item['href'] = i.xpath('a/@href').extract()[0] 25 #print(item) 26 27 yield item
说明:
1. 类的名字推荐按照这样书写,并且类的属性需要按照这样书写
2. 函数名和参数是固定的格式
3. 函数体内写爬虫规则,从18行开始就用到的是之前的xpath爬取方法了,区别是每行后面多了一个extract()
4. item格式是固定的字典型,并且要与items.py中定义的字段名称一致,因为16行item是xiaozhuItem( )的一个对象
5. 调试阶段可以在本文件中print看结果(但是需要运行整个项目而不是本文件)
6. 最后yield item 是迭代器,可以简单的认为是return函数吧,但是还是有很多很多不一样的地方,这个不展开说了
7. 还有个坑就是:第3行引入items.py中的类时,如果按照我这么写会提醒错误,解决方法是将工程文件作为Sources root。设置方法是在PyCharm中选择工程文件夹右键,选择倒数第二行的“Mark Dictionary as”-"Sources root"
pipelines.py 是写保存方法的,这里单纯的print一下结果
class XiaozhuPipeline(object): def process_item(self, item, spider): print(item) return item
mian.py 执行语句后面添加.split(),否则报错
from scrapy import cmdline cmdline.execute("scrapy crawl xiaozhu".split())
运行main.py 打印结果:
输出和我想象的不太一样呢……问了度娘说改成这样
scrapy crawl xiaozhu --nolog
再运行输出结果,bingo!