php抓取网页域名(scrapy创建一个新的Scrapy>scrapy#系统会在当前目录下创建项目名称 )
优采云 发布时间: 2021-12-19 00:04php抓取网页域名(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()