php抓取网页域名(scrapy创建一个新的Scrapy>scrapy#系统会在当前目录下创建项目名称 )

优采云 发布时间: 2021-12-19 00:04

  php抓取网页域名(scrapy创建一个新的Scrapy>scrapy#系统会在当前目录下创建项目名称

)

  1.scrapy爬虫的基本流程:

  1. 创建一个新的 Scrapy 项目

  >scrapy startproject 项目名称#系统会在当前目录下创建一个以项目名称命名的文件夹,里面收录如下文件:

  scrapy.cfg:项目配置文件

  items.py:需要解压的数据结构定义文件。在 items.py 中定义我们要捕获的数据:

  pipelines.py:管道定义,PipeLine用于保存Spider返回的Item列表,可以写入文件或数据库。

  settings.py:爬虫配置文件,包括发送请求数、间隔时间等。

  spiders:放置蜘蛛的目录,即爬虫的主程序。它至少收录以下三个元素: name:蜘蛛的标识符, parse() 方法:抓取start_urls中的网页时,需要调用该方法解析网页内容,同时需要返回到下一个需要爬取的网页,或者返回物品列表。start_url:蜘蛛开始爬取的 URL 列表。

  2. 定义需要从网页中提取的元素Item

  3. 实现一个Spider类,通过接口完成爬取URL和提取Item的功能

  4. 实现一个Item PipeLine类,完成Item的存储功能

  注意:

  > scrapy startproject huxiu2 #在当前文件夹下创建一个名为huxiu2的文件夹,该文件夹收录settings、items、pipeline等文件,构成一个爬虫框架

  自己写的爬虫程序应该写在projectname/projectname/spiders目录下

  2.配置items文件

  目标:抓取新闻列表的名称、链接地址和摘要。

  import scrapy

class HuxiuItem(scrapy.Item):

# define the fields for your item here like:

# name = scrapy.Field()

title=scrapy.Field()

link=scrapy.Field()

desc=scrapy.Field()

posttime=scrapy.Field()

  注:title、auther等将是每一行存储信息的items,即需要爬取的信息。

  输出和爬虫不在同一个文件中的好处是你以后可以在 Scrapy 中使用其他有用的组件和助手。虽然暂时感觉不是很深,但还是先按照框架来吧

  3.写第一个蜘蛛

  必备要素:如果使用items.py,必须先导入,继承scrapy.Spider类并有name、start_urls、parse。

  from huxiu2.items import Huxiu2Item #整个爬虫project的名字为huxiu2,

import scrapy

class Huxiu2Spider(scrapy.Spider):

name = "huxi2"

allowed_domains = [\'huxiu.com\'] # 只有这个域名下的子域名可以被允许爬取

start_urls = [\'http://www.huxiu.com/index.php\']

def parse(self, response):

for sel in response.xpath(\'//div[@class ="mod-info-flow"]/div/div[@class="mob-ctt index-article-list-yh"]\'):

item = HuxiuItem()

item[\'title\'] = sel.xapth(\'h2/a/text()\').extract_first()

item[\'link\'] = sel.xpath(\'h2/a/@href\').extract_first()

url = response.urljoin(item[\'link\'])

item[\'desc\'] = sel.path(\'div[@class ="mob-sub"]/text()\').extract_first()

print item[\'title\'],item[\'link\'], item[\'desc\']

#结果是无法爬取,估计需要设置headers。下文是修正版,啦啦啦,好from huxiu2.items import Huxiu2Item #整个爬虫project的名字为huxiimpofrom huxiu2.items import Huxiu2Item

  import scrapy

class Huxiu2Spider(scrapy.Spider):

name = "huxiu"

# allowed_domains = [\'huxiu.com\'] # 只有这个域名下的子域名可以被允许爬取

# start_urls = [\'http://www.huxiu.com\'] #有了重定义的start_requests就不用start_urls啦

def start_requests(self):

# start_urls作用是开始请求第一个网址,默认就是使用start_requests方法,不带任何参数地请求,现在我们为了爬取信息必须要带上参数,

# 所以我们要自定义一下这个方法。

# 下方的request默认参数是:url, callback=None, method=\'GET\', headers=None, body=None,cookies=None, meta=None, encoding=\'utf-8\',

# priority=0,dont_filter=False, errback=None, flags=None。 所以cookie和headers是分开的,至于其余的参数,以后详解

url=\'http://www.huxiu.com/index.php\'

head={

"User-Agent":"info"

}

cookie={\'key\':\'value\'} #自己去网页f12看哦,复制以后改成字典格式

yield scrapy.Request(url=url,cookies=cookie,callback=self.parse,headers=head)

pass

def parse(self, response):

print ">>>>>呵呵"

for i in response.xpath(\'//div[@class="mod-b mod-art clearfix "]\'):

item=Huxiu2Item()

item[\'title\'] = i.xpath(\'./div[@class="mob-ctt index-article-list-yh"]/h2/a/text()\').extract_first()

item[\'link\']=i.xpath(\'./div[@class="mob-ctt index-article-list-yh"]/h2/a/@href\').extract_first()

item[\'desc\']=i.xpath(\'.//div[@class="mob-sub"]/text()\').extract_first()

print item[\'title\'],item[\'link\'],item[\'desc\']

  4.处理链接进入各个文章获取信息

  在items.py文件中,我们定义了posttime=scrapy.Field(),但是发送时间只有打开具体的文章后才能获取,所以我们要同时处理二级URL .

  from huxiu2.items import Huxiu2Item #整个爬虫project的名字为huxiu2,

import scrapy

class Huxiu2Spider(scrapy.Spider):

name = "huxi3"

allowed_domains = [\'huxiu.com\'] # 只有这个域名下的子域名可以被允许爬取

start_urls = [\'http://www.huxiu.com\'] #相当于第一次发出请求

def parse(self, response):

for sel in response.xpath(\'//div[@class ="mod-info-flow"]/div/div[@class="mob-ctt index-article-list-yh"]\'):

item = HuxiuItem() #实例化一个item用于储存数据

item[\'title\'] = sel.xapth(\'h2/a/text()\').extract_first()

item[\'link\'] = sel.xpath(\'h2/a/@href\').extract_first()

url = response.urljoin(item[\'link\']) #生成可访问的打开每一篇文章的新网址

item[\'desc\'] = sel.xpath(\'div[@class ="mob-sub"]/text()\').extract_first()

print item[\'title\'],item[\'link\'], item[\'desc\']

yield scrapy.Request(url,callback=self.parse_artical) #开始第二层的请求,网址是url,callbac参数定义的是第二层爬取将调动哪个函数

def parse_artical(self,response):

item=Huxiu2Item() #同样需要实例一下用来储存数据

item[\'posttime\']=response.xpath(\'//span[@class="article-time pull-left"]/text()\').extract_first()

item[\'link\']=response.url #进去第二层以后顺带更新一下litem[\'link\'],因为之前的link不完整,不用之前的url变量是因为在此处更新可以确保新网址可打开。

print item[\'posttime\'],item[\'link\']

yield item

  5.导出爬取数据

  第一种方法:直接打印:>scrapy crawl huxi3

  第二种方法:将结果导出到一个jason文件中:>scrapy crawl huxiu -o items.json

  第三种方法:保存到数据库

  保存到数据库中,可以直接在spider中定义,也可以使用piplines

  直接用spider写的方法:

  from huxiu2.items import Huxiu2Item #整个爬虫project的名字为huxiu2,

import scrapy,pymysql

class Huxiu2Spider(scrapy.Spider):

name = "huxiu"

def start_requests(self):

url=\'http://www.huxiu.com/index.php\'

head={

"User-Agent":"xxx"

}

cookie={

"xxx": "yyy"

}

yield scrapy.Request(url=url,cookies=cookie,callback=self.parse,headers=head)

pass

def parse(self, response):

db = pymysql.connect("localhost", "root", "xxxx", "xxxx") #先要连接上数据库

cursor = db.cursor()

sql="""create table huxiu(`title` varchar(50),`link` varchar(50),`desc` varchar(50))DEFAULT CHARSET=utf8""" #设置数据表的编码方式

try:

cursor.execute(sql) #创建数据表新表

db.commit()

except:

db.rollback()

print "error first try"

for i in response.xpath(\'//div[@class="mod-b mod-art clearfix "]\'):

item=Huxiu2Item()

item[\'title\'] = i.xpath(\'./div[@class="mob-ctt index-article-list-yh"]/h2/a/text()\').extract_first().encode("utf-8")

tmplink=i.xpath(\'./div[@class="mob-ctt index-article-list-yh"]/h2/a/@href\').extract_first().encode("utf-8")

item[\'link\']=response.urljoin(tmplink).encode("utf-8")

item[\'desc\']=i.xpath(\'.//div[@class="mob-sub"]/text()\').extract_first().encode("utf-8") #加encode的原因是原数据是unicode格式的

#print \'第一层\',item[\'title\'],item[\'link\'],item[\'desc\']

a=str(item[\'title\'])

b=str(item[\'link\'])

c=str(item[\'desc\'])

print item[\'title\'],"结果"

sql2="""INSERT INTO huxiu VALUES (\'%s\', \'%s\',\'%s\')""" % (a,b,c) #传参到sql语句中,%s表示传的是字符串

try:

cursor.execute(sql2)

db.commit()

except:

db.rollback()

print "error of second try"

db.close()

  管道的使用方法:

  注意:要使用管道,

  首先,蜘蛛中必须有一个yield item作为结尾,只要这个可以生成item,否则item为空;

  其次,必须在settings中启用pipeline,格式如下:ITEM_PIPELINES = {\'huxiu2.pipelines.Huxiu2PipelinesJson\': 300,},字典的key是自定义的pipeline函数名

  最后要注意的是,管道中的类下基本有3个函数,分别在开头、中间和结尾执行。

  蜘蛛的代码:

  from huxiu2.items import Huxiu2Item #整个爬虫project的名字为huxiu2,

import scrapy,pymysql

class Huxiu2Spider(scrapy.Spider):

name = "huxiu"

def start_requests(self): #自定义的request方法

url=\'http://www.huxiu.com/index.php\'

head={

"User-Agent":"yyy"

}

cookie={

"xxx": "yyy"

}

yield scrapy.Request(url=url,cookies=cookie,callback=self.parse,headers=head)

pass

def parse(self, response): #自定义的信息获取函数

for i in response.xpath(\'//div[@class="mod-b mod-art clearfix "]\'):

item=Huxiu2Item()

item[\'title\'] = i.xpath(\'./div[@class="mob-ctt index-article-list-yh"]/h2/a/text()\').extract_first().encode("utf-8")

tmplink=i.xpath(\'./div[@class="mob-ctt index-article-list-yh"]/h2/a/@href\').extract_first().encode("utf-8")

item[\'link\']=response.urljoin(tmplink).encode("utf-8")

item[\'desc\']=i.xpath(\'.//div[@class="mob-sub"]/text()\').extract_first().encode("utf-8")

print \'第一层\',item[\'title\'],item[\'link\'],item[\'desc\'] #为了看到是否可以成功爬取信息,为了搞明白pipelines的原理

yield item #yield item非常必要

  管道代码:

  # -*- coding: utf-8 -*-

# Define your item pipelines here

#

# Don\'t forget to add your pipeline to the ITEM_PIPELINES setting

# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html

import json

class Huxiu2PipelinesJson(object):

def __init__(self):

print \'开始时候执行\' #在得到有用数据以前打印出来

self.file=open(\'Huxiu.json\',\'w\') #会在当前目录生成Huxiu.json文件

def process_item(self, item, spider):

print \'process_item running\' #每次print一组信息以后就会打印出这句话,说明item是一条一条写进json文件中的,而不是生成item以后再总的写进去

content=json.dumps(dict(item),ensure_ascii=False)+\'\n\' #python信息转化为json信息的函数

self.file.write(content)

return item

def close_spider(self,spider):

print \'结束时候\' #有用的信息执行完毕后打印出来这句话

self.file.close()

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线