一亩三分地论坛

 找回密码
 Sign Up 注册获取更多干货
码农求职神器Triplebyte:
不用海投,内推多家公司面试
Airbnb 数据科学职位
in analytics and inference
游戏初创公司
招聘工程师、Designer和游戏策划
游戏初创公司DreamCraft招聘工程师、UIUX Designer和游戏策划
把贵司招聘信息放这里
查看: 11888|回复: 9
收起左侧

[DataScience] 手把手教你用python抓网页数据II(scrapy版)

    [复制链接] |试试Instant~ |关注本帖
victorsterling 发表于 2015-6-23 15:51:48 | 显示全部楼层 |阅读模式

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看,没有帐号?Sign Up 注册获取更多干货

x
本帖最后由 victorsterling 于 2015-10-28 22:18 编辑

The whole code in github: https://github.com/victorsterling1/news_spider_scrapy
. 1point 3acres 璁哄潧
前言:

之前超级玛丽大神写了一个利用python的urllib,urllib2的module去抓取网页数据(链接:手把手教你用python抓网页数据)。这个帖子对我的帮助很大,也让我学习了很多知识。在此,我来好好膜拜一下超级玛丽大神。
.鏈枃鍘熷垱鑷1point3acres璁哄潧
作为转专业的学鶸,几个月前难得在北京混了一份技术岗的实习,工作学的算是能熟练一点的技能也就只有爬虫了。有难度的代码都搞得不太懂(没基础的zhazha求不鄙视)。在我码代码的过程中,地里的很多大神跟给我提供了很多的建议和帮助,在此感谢各位大神的帮助,同时在这里也分享一下我自己对于使用pyhton爬虫的一些心得。


就像超级玛丽之前说的,python和网页相关的几个module除了urllib,urllib2,httplib之外,还有mechanize和scrapy等。在这里,我使用的是scrapy去做网络爬虫。
. from: 1point3acres.com/bbs

新手码的代码或许会有很多不尽人意的地方,希望各位大神多多指点,此帖子也仅仅是抛砖引玉,欢迎大家多多讨论。(大神们请尽情喷我代码写的烂吧


步骤一:准备工作
首先要熟悉python的基本知识和使用方法,在这里推荐一门university of Michigan的公开课人人都懂的编程课(Python)。本人今年年初跟的这门课,作为无基础的zhazha,我表示这门课学起来非常简单,毫不费力(估计也是因为这门课是基础中的基础),非常适合转专业的新手去学习。跟完之后对python的基本用法也大致有了了解。
(但是我实际工作中经常会有这种感慨:卧槽!这些代码都是啥?!!我TM真的学过Python吗??-google 1point3acres

对python有了一定了解后,请安装好pyhton,设置好环境参量,并安装scrapy模块,教程如下:
installation guide

. more info on 1point3acres.com
其它需要的module在实际应用中,就见到需要什么就装什么,反正大多都可以在shell(cmd)中用pip install XX 就可以了。

步骤二:创建自己的项目
scrapy安装完毕之后,就可以开始创建自己的项目了。比如:我们要去做一个从各大新闻网站抓取新闻内容的爬虫。我们就需要从网页中提取标题,正文,日期等信息。. 鐗涗汉浜戦泦,涓浜╀笁鍒嗗湴

首先,打开cmd,输入scrapy startproject news
就可以创建一个名字为news的项目。一般默认在我的文档目录下生成文件。文件目录如下:
news:.│  scrapy.cfg
│└─news   
   │  items.py    . 鐣欏鐢宠璁哄潧-涓浜╀笁鍒嗗湴
   │  pipelines.py   
   │  settings.py   
   │  __init__.py   
   │ └─spiders           
             __init__.py. visit 1point3acres.com for more.
  • scrapy.cfg: 项目配置文件
  • news/: 项目python模块, 呆会代码将从这里导入
  • news/items.py: 项目items文件
  • news/pipelines.py: 项目管道文件
  • news/settings.py: 项目配置文件
  • news/spiders: 放置spider的目录

步骤三:定义我们要提取的数据(item)

Items是将要装载抓取的数据的容器,它工作方式像python里面的字典,但它提供更多的保护,比如对未定义的字段填充以防止拼写错误。
我们使用IDLE(python自带编译器)打开items.py编辑代码,即可完成对item的定义。
  1. from scrapy.item import Item, Field


  2. class NewsItem(Item):
  3.     -google 1point3acres
  4.     title = Field(). 鐗涗汉浜戦泦,涓浜╀笁鍒嗗湴
  5.     link = Field()
  6.     content = Field()
  7.     date = Field()
复制代码
步骤四:写爬虫(spider)
. 1point 3acres 璁哄潧
. 鐣欏鐢宠璁哄潧-涓浜╀笁鍒嗗湴
scrapy给提供的spider有很多种,如:BaseSpider,CrawlSpider,XMLFeedSpider,CSVFeedSpider等等。(关于spider的详细介绍和用法请看这里:手册链接). 鐗涗汉浜戦泦,涓浜╀笁鍒嗗湴


其中最简单的是BaseSpider,最常用的是CrawlSpider,在这里我对这俩种进行介绍:


进入spider目录,在这个目录下新建一个py文件,名字就是spider的name,然后进行编辑。. 1point3acres.com/bbs


首先是BaseSpider (or Spider):
个人感觉比较适合爬一些有针对性的那种网页,比如:某一个新闻网站某子版块的新闻数据。-google 1point3acres
下面是一个爬搜狐新闻网站环保版块新闻的例子。
  1. # -*- coding: utf-8 -*-
  2. import scrapy
  3. from news.items import NewsItem. From 1point 3acres bbs
  4. from scrapy.http import Request
  5. import requests
  6. import re


  7. class SohuSpider(scrapy.Spider):
  8.     name = "sohu"
  9.     allowed_domains = ["gongyi.sohu.com"]
  10.     start_urls = (
  11.                 'http://gongyi.sohu.com/hbdt/',
  12.                 #'http://gongyi.sohu.com/gongyiyw/'
  13.                 #'http://gongyi.sohu.com/salon/index.shtml'
  14.                 #'http://gongyi.sohu.com/focus/index.shtml'
  15.                 #'http://gongyi.sohu.com/gongyicehua/'
  16.         )
  17.     def __init__(self):
  18.         
  19.         self.count = 33. more info on 1point3acres.com

  20.     def parse(self, response):
  21.         try:
  22.             lis = response.css('div[class="f14list"]').xpath('ul').xpath('li')
  23.             for li in lis:
  24.                 item = EnvItem()
  25.                 item['link'] = li.xpath('a/@href').extract()[0]
  26.                 if not li.xpath('a/text()'):
  27.                         continue
  28.                 item['title'] = li.xpath('a/text()').extract()[0]
  29.                 link_info = item['link'].split("/")
  30.                 link_info2 = link_info[-2]
  31.                 item['date'] = link_info2[:4] + '-' + link_info2[4:6] + '-' + link_info2[6:]
  32.                

  33.                 r = requests.get(item["link"])-google 1point3acres
  34.                 r.encoding=r.apparent_encoding
  35.                 data = r.text
  36.                 link_list = re.findall('<p>(.*?)</p>' ,data)
  37.                 item["content"] = ''
  38.                 if  link_list:.鏈枃鍘熷垱鑷1point3acres璁哄潧
  39.                     item["content"] = ''.join(link_list)-google 1point3acres
  40.                 else : 鏉ユ簮涓浜.涓夊垎鍦拌鍧.
  41.                     print 'NONE'
  42.                 yield item. From 1point 3acres bbs

  43.         except:
  44.             pass


  45.         if self.count>0:
  46.             url = "http://gongyi.sohu.com/hbdt/index_" + str(self.count) + ".shtml"
  47.             print url
  48.             self.count -= 1-google 1point3acres
  49.             yield Request(url, callback = self.parse)
复制代码
其次是CrawlSpider:
这个就更加粗暴一些,通rule规则去爬此网站域名下所有的网页,再根规则从中选择想要提取数据的网页进行数据提取,(简单粗暴,不过感觉大数据分析抓数据就该这么粗暴地大规模抓数据吧

. 鍥磋鎴戜滑@1point 3 acres
下面是一个爬地方性新闻网站的例子。
  1. #-*-coding:utf-8-*-
  2. #Author: Victor. Waral 鍗氬鏈夋洿澶氭枃绔,
  3. #Date: 2015-6-18. visit 1point3acres.com for more.
  4. import re
  5. import scrapy
  6. from scrapy.contrib.spiders import CrawlSpider, Rule
  7. from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
  8. from scrapy.selector import HtmlXPathSelector
  9. from scrapy.http import Request. from: 1point3acres.com/bbs
  10. from scrapy.selector import HtmlXPathSelector
  11. import time
  12. . From 1point 3acres bbs
  13. from news.items import NewsItem
  14. . 鐣欏鐢宠璁哄潧-涓浜╀笁鍒嗗湴
  15. class HongSpider(CrawlSpider):
  16.     name = 'hong'

  17.     allowed_domains = ['rednet.cn']
  18.     start_urls = ["http://china.rednet.cn/"]
  19.     rules = (. 鐗涗汉浜戦泦,涓浜╀笁鍒嗗湴
  20.         Rule(SgmlLinkExtractor(allow=(r'http://.*.rednet.cn/[cC]/[0-9]+/[0-9]+/[0-9]+/[0-9]+.htm'), unique=True),callback='parse_item'),
  21.         Rule(SgmlLinkExtractor(allow=(r'http://.*.rednet.cn/[cC].*.*'), unique=True)),
  22.         
  23.         ). 1point 3acres 璁哄潧
  24. . from: 1point3acres.com/bbs
  25. -google 1point3acres
  26.     def parse_item(self, response):
  27.         try:
  28.             hxs = HtmlXPathSelector(response)
  29.             item = NewsItem()
  30.             item['link'] = response.url
  31.             item['title'] = hxs.select("//head/title/text()").extract()[0]
  32.             time_raw = item['link'].split('/')
  33.             item['date'] = time_raw[-4] + "-" + time_raw[-3] + "-" + time_raw[-2]. 鐣欏鐢宠璁哄潧-涓浜╀笁鍒嗗湴
  34.         
  35.             item['content'] = ''
  36.             content_list = hxs.select("//div[@id='articlecontent']/p/text()").extract()
  37.             if content_list ==[]:
  38.                 content_list = hxs.select("//div[@id='articlecontent']/P/text()").extract()
  39.             if content_list ==[]:
  40.                 content_list = hxs.select("//div[@id='articlecontent']/FONT/text()").extract()
  41.             if content_list ==[]:. 涓浜-涓夊垎-鍦帮紝鐙鍙戝竷
  42.                 content_list = hxs.select("//div[@id='articlecontent']/text()").extract()
  43.             if content_list ==[]:
  44.                 content_list = hxs.select("//font[@id='zoom']/text()").extract()
  45.             if content_list ==[]:. from: 1point3acres.com/bbs
  46.                 content_list = hxs.select("//div[@id='zoom']/text()").extract()
  47.             if content_list:
  48.                 item['content'] = ''.join(content_list)
  49.             else:
  50.                 print 'None'
  51.             if item['content'] == '':
    -google 1point3acres
  52.                 item['content'] = "null"
  53.             yield item
  54.             time.sleep(1)

  55.         except:
  56.             pass
  57.      
复制代码
步骤五:设置存储文件的方式和项目设置


先设置项目的setting:
打开之前的生成的settings.py,编译代码
  1. BOT_NAME = 'news'


  2. SPIDER_MODULES = ['news.spiders']
  3. NEWSPIDER_MODULE = 'news.spiders'
  4. ITEM_PIPELINES = [
  5.     'news.pipelines.NewsPipeline']

  6. USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; rv:38.0) Gecko/20100101 Firefox/38.0'
复制代码
其实,前面那几行都已经自动生成好了,我们所需要做的仅仅只是设置一个user_agent而已。这个东西,自己去常用的浏览器找找看能不能看到吧。

虽然我觉得这东西并没有什么卵用······我之前忘记设置了也照样能爬。不过还是严谨一点比较好。

然后是对项目储存方式的设置:. 1point3acres.com/bbs
打开之前生成的pipelines.py,进行编译
  1. import json
  2. import codecs. 1point3acres.com/bbs
  3. from os import path. Waral 鍗氬鏈夋洿澶氭枃绔,
  4. from scrapy import signals

  5. class NewsPipeline(object):
  6.     def __init__(self):. 鐗涗汉浜戦泦,涓浜╀笁鍒嗗湴
  7.         self.file = codecs.open('raw_data.json', 'w',"utf-8")
  8.     def process_item(self, item, spider):
  9.         line = json.dumps(dict(item)) + "\n"
  10.         self.file.write(line). 鍥磋鎴戜滑@1point 3 acres
  11.         return item
复制代码
将数据保存为json文件,方便之后转换成数据库文件。

当然,如果你想直接需要用,而不是看那些json文件里面看不懂的unicode编码的话,我下面介绍一种可以直接拿出来用的保存方式。
  1. import json
  2. import codecs
  3. from os import path. more info on 1point3acres.com
  4. from scrapy import signals

  5. class NewsPipeline(object):
  6.     def __init__(self):
  7.         self.file = codecs.open('raw_data.doc', 'w','utf-8'). 1point3acres.com/bbs
  8.     def process_item(self, item, spider):        
  9.         self.file.write(item['title']+"\n")
    .鏈枃鍘熷垱鑷1point3acres璁哄潧
  10.         self.file.write(item['link']+"\n")
  11.         self.file.write(item['date']+"\n")
  12.         self.file.write(item['content']+"\n")
  13.         return item
  14.         file.close()
复制代码

步骤六:万事俱备,让我们开始爬吧


. 1point3acres.com/bbs
在news文件夹下,按住shift右击,然后选择进入命令窗口,输入:
scrapy crawl hong     #hong是我们其中一个spider的name.鏈枃鍘熷垱鑷1point3acres璁哄潧

就可以开始爬啦。

提取数据的文件将保存在当前目录下。

. 鐣欏鐢宠璁哄潧-涓浜╀笁鍒嗗湴
欢迎各位大神多多指点我代码上的不足哈。大家多多讨论。
. 鐣欏鐢宠璁哄潧-涓浜╀笁鍒嗗湴

.1point3acres缃
.鐣欏璁哄潧-涓浜-涓夊垎鍦
. 涓浜-涓夊垎-鍦帮紝鐙鍙戝竷

. more info on 1point3acres.com


. 鐣欏鐢宠璁哄潧-涓浜╀笁鍒嗗湴
.1point3acres缃

评分

12

查看全部评分

joycevernon 发表于 2015-6-27 15:48:55 | 显示全部楼层
Python不熟但是感觉很有用啊,有空的时候follow介个练习~~谢谢楼主!!
回复 支持 反对

使用道具 举报

 楼主| victorsterling 发表于 2015-6-27 21:07:39 | 显示全部楼层
joycevernon 发表于 2015-6-27 15:48
Python不熟但是感觉很有用啊,有空的时候follow介个练习~~谢谢楼主!!

好嘞,大家互相交流哈!
资历最老的留学申请文书修改服务:EssayEdge
College Essay Editing Service
回复 支持 反对

使用道具 举报

youhusky 发表于 2015-6-27 21:19:18 | 显示全部楼层
Follow 楼主,我也学习
回复 支持 反对

使用道具 举报

xongkoro 发表于 2015-7-3 10:48:09 | 显示全部楼层
谢谢LZ分享。还有一个BeautifulSoup也很好用。
回复 支持 反对

使用道具 举报

pilot_g2 发表于 2015-7-8 15:05:30 | 显示全部楼层
谢谢楼主分享,学习了!
回复 支持 反对

使用道具 举报

 楼主| victorsterling 发表于 2015-7-8 17:37:33 | 显示全部楼层
xongkoro 发表于 2015-7-3 10:48
谢谢LZ分享。还有一个BeautifulSoup也很好用。

最近用了一下beautifulsoup,感觉这个跟scrapy相比还是差很多啊,很难实现一些html节点的精准抓取,只是一些常用的,笼统的数据提取,感觉不是很有效力。还是说我自己的用的不地道??
回复 支持 反对

使用道具 举报

calalia 发表于 2015-7-21 09:51:02 | 显示全部楼层
强力马可马可马可!!!!!!!!!
回复 支持 反对

使用道具 举报

 楼主| victorsterling 发表于 2015-10-28 22:20:33 | 显示全部楼层
已把整体的code上传到github上,大家想要实践的话,可以直接下载下来试试看。
回复 支持 反对

使用道具 举报

本版积分规则

关闭

一亩三分地推荐上一条 /5 下一条

手机版|小黑屋|一亩三分地论坛声明

custom counter

GMT+8, 2018-1-18 04:40

Powered by Discuz! X3

© 2001-2013 Comsenz Inc. Design By HUXTeam

快速回复 返回顶部 返回列表