脱离八爪鱼,最近两天用scrapy爬了一个商品网站,本来可以快很多的,其中有一天把时间花在一行代码上最后绕了一大圈改了个参数就解决了??希望大家少走点弯路。
很多都是对慕课网的一个总结,网址:https://www.imooc.com/video/17519
讲得非常好!
比较敏感所以用课程的代码例子了。
第一次写,难免不专业多多指教。
1.新建项目
第一步先安装,可以按照视频上安装,略。
例子中,我们要爬的是:https://movie.douban.com/top250
首先:
scrapy startproject douban
就创建好了一个文件夹叫douban
在cmd上进入到douban文件夹中cd douban
,再进入子目录cd douban/
好的,现在我们需要与网站相关联的一个包,cmd输入
scrapy genspider douban_spider movie.douban.com
然后我们就可以用pycharm或者sublime把包导进去check一下
不要紧张,如果你的和我不一样,那么应该在douban目录下新建一个文件叫main.py
找到Settings.py文件 -> 找到被#掉的user agent -> (这个不是真正的user agent,我们需要打开https://movie.douban.com/top250,win直接F12,Mac就option+command+I ,打开检查栏)
把黑字复制了拷在settings.py上的user agent后面就好,别忘了去掉注释
2.快捷运行
在main.py文件中,让他代替终端的功能,在环境中运行就好
from scrapy import cmdline
cmdline.execute('scrapy crawl douban_spider'.split())
3. 修改douban_spider.py
先贴上源码
# -*- coding: utf-8 -*-
import scrapy
from douban.items import DoubanItem
class DoubanSpiderSpider(scrapy.Spider):
name = 'douban_spider'
allowed_domains = ['movie.douban.com']
start_urls = ['http://movie.douban.com/top250']
def parse(self, response):
movie_list = response.xpath("//div[@class='article']//ol[@class='grid_view']/li")
for i_item in movie_list:
douban_item = DoubanItem()
douban_item['serial_number'] = i_item.xpath(".//div[@class='item']/div[@class='pic']/em/text()").extract_first()
douban_item['movie_name'] = i_item.xpath(".//div[@class='info']/div[@class='hd']/a/span[1]/text()").extract_first()
content = i_item.xpath(".//div[@class='info']/div[@class='bd']/p[1]/text()").extract()
for i_content in content:
content_s = "".join(i_content.split())
douban_item['introduce'] = content_s
douban_item['star'] = i_item.xpath(".//span[@class='rating_num']/text()").extract_first()
douban_item['evaluate'] = i_item.xpath(".//div[@class='star']//span[4]/text()").extract_first()
douban_item['describe'] = i_item.xpath(".//p[@class='quote']/span/text()").extract_first()
yield douban_item
next_link = response.xpath("//span[@class='next']/link/@href").extract()
if next_link:
next_link = next_link[0]
yield scrapy.Request("http://product.asmag.com.cn"+next_link,callback=self.parse)
首先导入两个包
import scrapy
from douban.items import DoubanItem
然后稍作修改:把start_urls改为我们的代码头,什么叫代码头呢??
代码头就是每一页自动翻页时,保持不变的一段代码。
打个比方,
爬取网页某一页的第一页是 https://www.baidu.com/0-0-1.html
爬取网页某一页的第二页是 https://www.baidu.com/0-0-2.html
那么 https://www.baidu.com 就是代码头
start_urls = ['http://movie.douban.com/top250']
下面进入方法的编写
(首先我们要先学会检查元素)
先找到items这个文件,我们需要先对于抓取目标做个定义。在本例中,我们抓取这6个元素。
然后我们开始找到douban_spider.py ,写
movie_list = response.xpath("//div[@class='article']//ol[@class='grid_view']/li")
创建movie_list,潜入一个根目录??意思就是在面对html的时候我们检查的文本元素基本都出现在div/ol/li以后,仔细观察下面被折叠的 < li >…< / li >,就是一页中25个项目的详细信息。
接下来这一步就不详细说了,就是在i_item里面改代码
分别找到每个元素的定位
for i_item in movie_list:
douban_item = DoubanItem()
douban_item['serial_number'] = i_item.xpath(".//div[@class='item']/div[@class='pic']/em/text()").extract_first()
douban_item['movie_name'] = i_item.xpath(".//div[@class='info']/div[@class='hd']/a/span[1]/text()").extract_first()
content = i_item.xpath(".//div[@class='info']/div[@class='bd']/p[1]/text()").extract()
for i_content in content:
content_s = "".join(i_content.split())
douban_item['introduce'] = content_s
douban_item['star'] = i_item.xpath(".//span[@class='rating_num']/text()").extract_first()
douban_item['evaluate'] = i_item.xpath(".//div[@class='star']//span[4]/text()").extract_first()
douban_item['describe'] = i_item.xpath(".//p[@class='quote']/span/text()").extract_first()
yield douban_item #抛回处理
记住,最重要的是:
- xpath后面的 “.” 别忘了,这个点的作用就是基于前面movie_list的地址作为根目录,作为根目录向下访问。
- yield douban_item不能漏掉,一定要抛回
- 对于introduce 这一项,因为内容都是分行显示的,所以我们也要用一个循环来完成正常的抓取。
- 对于xpath的使用可以看看我上面说的或者上网查一下xpath语法。
最后,自动翻页。
感叹一句,豆瓣真的太友好了!下一页按钮存在,那么每次就执行下一页元素指向的网址就好了。
next_link = response.xpath("//span[@class='next']/link/@href").extract()
if next_link:
next_link = next_link[0]
yield scrapy.Request("http://product.asmag.com.cn"+next_link,callback=self.parse)
if后面的意思就是,如果还有下一页获取到的网址就一直进行下去啦!
但是在我做的项目中并没有下一页。。我是这样处理的
next_link = response.xpath("//div[@class='listpage']/a[@class='on']/following-sibling::a/@href").extract()
思想就是通过找到这个a[@class=‘on’]的元素,这代表当前在的页面,然后我们查找他的 /following-sibling::a/
也就是下一个兄弟元素,再获取/@href就好。
除此之外,我还试过BeautifulSoup的方法还有cssselect的get方法,但是对于这类抓取来说不太有必要。
3.保存文件
激动人心的时刻。回到cmd。
scrapy crawl douban_spider -o test.csv
保存为csv格式,进到douban文件夹就能看到了
但是通过excel我们会发现它乱码!awsl
没事 win可以通过记事本打开另存为修改编码
mac用户参照这个链接:https://www.jianshu.com/p/0a3f587f630e
嗯,完美解决。