scrapy框架爬虫新闻网站步骤

up主学了段时间的爬虫,因为马上要学习其他内容了,想记录一下自己那时做的步骤。
纯手打》》

First(准备工作):
装好conda、python、pycharm环境下,命令行键入scrapy startproject 爬虫项目名(
一般是域名+Spider就可以了 如BaiduSpider),之后键入cd 爬虫项目名 进入该路径下,再键入scrapy genspider 爬虫名(自己起一个比如baidu_spider) 域名(如baidu.com

Second(开始干啦)
打开最强的pycharm,哦对了,刚默认已经装了scrapy框架,没装的可以通过命令行键入conda install scrapy 来安装scrapy。
打开刚刚的文件,首先开始撰写爬虫文件(就是刚刚的名字为爬虫名的文件),在撰写该文件之前要对setting进行设置下,以免出现很多不愉快的东西。
1.打开文件里的setting 加入LOG_LEVEL = "WARN"这样很多不需要看到的内容就不会打印了,只有正常打印和警告以及Error才会显示。
2.设置settings里面的ROBOTSTXT_OBEY = True 默认是True 需要改成False否则无法访问网页。
3.有的时候需要设置延时,只需要将settings里面的#DOWNLOAD_DELAY = 3 解除封印即可,延迟时间可变 0.6 就好了,有些网页延迟大就得设置。
4.之后在将抓取内容放到本地数据库的时候需要将settings里面的#ITEM_PIPELINES = {
‘TheJapan.pipelines.ThejapanPipeline’: 300,
}
这条语句解除封印,不然会存储失败。

设置好setting文件我们还需要对item文件进行撰写:
撰写内容之前需要对网站进行考察,考虑抓取哪些有用的信息,将它们作为类放到item里,如图示
在这里插入图片描述
这里我需要抓取文章更新世家、标题、内容等信息,所以撰写成如图所示。

下面开始撰写爬虫啦:

	《1》首先引入所需模块
	比如

import scrapy
from TheJapan.items import ThejapanItem
from scrapy.http import Request

《2》之后下面自动生成的信息进行修改(正确就不用改了)
以下所有内容都是在文件刚开始生成的类下编写

name = 'Japan'
allowed_domains = ['the-japan-news.com']			#域
start_urls = ['http://the-japan-news.com/']   #需要访问的首页


 《3》接着撰写请求头

在这里插入图片描述
请求头的信息在访问网页源代码时查看(F12)

# 重写方法,设置请求头(其实有更简单的方法,在settings里设置default-headers就行了
def make_requests_from_url(self, url):
    return Request(url, headers=self.headers, dont_filter=True)

加上这段

《4》 下面开始编写解析函数比如我之前爬的一个日本新闻网站:

 def parse(self, response):
    pages10 = response.xpath('//*[@id="rootHeader"]/div[3]/div/nav/ul/li/a/text()').extract()
    pages8 = pages10[1:10]
    # print(pages8)
    for page in pages8:
        page = "http://the-japan-news.com/news/" + page
        print("拼接后的模块链接: ", page)
        yield Request(page, callback=self.Parsepage)
        
 def Parsepage(self, response):
    print("下面开始对每一个导航页进行解析:")
    news = response.xpath("//*[@id='newsSubgenreListWrapper']/section/ul/li/article/a/@href").extract()

    for new in news:
        new = "http://the-japan-news.com" + new
        print("拼接后的单条新闻链接:", new)
        try:
            yield Request(new, callback=self.Parsenew)
        except:
            pass
    ......
    下面还要有解析单条新闻的函数以及将之存放到item里面的操作,抓取内容我用的xpath,本人不熟练正则表达式方法,简单的xpath可以解决很多,如果有些内容在不太好抓的地方,或者字段内,就可以使用正则去抓,当然对于抓取在字段内的有时候也可以用xpath先抓下来然后在对内容进一步处理(如果不嫌麻烦。。)

ps:可以先设置self.ok = True 来判断内容是否存到数据库,对于每一个item内容域,通过try,except 来实现,except 之后将self.ok置为False 然后最后yield返回时如果
是False就yield item 否则就报错:

    if self.ok:
        yield item
    else:
        print("有问题:", item)
        return 0

《5》下面撰写管道文件(存储到本地数据库)

同样首先引入所需模块
from scrapy.exceptions import DropItem
import pymysql
import time
import requests
import pathlib
import urllib
import os
import urllib.request
import sys
import pymysql.cursors
import urllib.parse
import hashlib
import random
import json
from Frenchlib import TextTranslation
from aip import AipSpeech

我这里用到软件翻译,所以最后两个可以不用管。

<1>首先连接本地数据库(默认安装好了mysql,以及可视化Navicat12,并且在本地数据库 创建好了下面所提到的表,以及表中项)

class ThejapanPipeline(object): #之后所有内容都在这个大类下
# 在构造函数中连接数据库
def init(self):
config = {
‘host’: ‘这个保密’, # 默认本地连接
‘user’: ‘这个保密’,
‘password’: ‘这个保密’,
‘port’: 3306, # 默认端口号3306
‘database’: ‘japan’,
‘charset’: ‘utf8’, # 默认即为utf8
}

    try:
        self.sqljapan = pymysql.connect(**config)
        print('connect succeed')
    except pymysql.Error as e:
        print('connect fails!{}'.format(e))
        
def process_item(self, item, spider):
    # print(item)
    print(">>>>>>>>>>>>>>>>>>>>>>")
    print('下面进入数据库存储')
    cur = self.sqljapan.cursor()
    sql_0 = "select NewsID from newstitle WHERE Title = %s "     # sql语句存储数据,并进行滤重
    params_0 = (item['title'])
    cur.execute(sql_0, params_0)
    if not cur.fetchall():   #滤重
        try:
            js = test.start(yuan, mubiao, item['title'])   #翻译段,不用管
            data = json.loads(js)
            # print(data)
            Title_cn = data['data']['target_text']    #这里是之前翻译的 不用管
        except:
            pass
        creattime = time.strftime("%Y/%m/%d %H:%M:%S", time.localtime())     		#记录本地时间
        Sql_1 = "INSERT INTO newstitle(Title, Title_cn, office, Url, Pic, PicDesc, CreatTime, PublishTime, newsfrom, wordcount) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
        params_1 = (item['title'], Title_cn, item['office'], item['URL'], item['pic'], item['picDesc'], creattime, item['update'], 'Japannews', item['wordcount'])
        # print("打印sql:", Sql_1)
        cur.execute(Sql_1, params_1)      #执行sql语句
        self.sqljapan.commit()							#提交
        rows = cur.rowcount						#如果没查到这条记录那么rowcount返回零,否则返回插入的记录条数
        if rows == 0:
            raise DropItem("Already in the database.")  #过滤

        Sql_2 = 'select NewsID from newstitle where Title = %s'
        params_2 = (item['title'])
        cur.execute(Sql_2, params_2)
        newsID = cur.fetchall()[0][0]

        # body = item['content']
        # bd = ' '.join(body)
        Sql_3 = "insert into newstext(Sentence,NewsID,ImgPath,ImgDesc) values (%s,%s,%s,%s)"
        params_3 = (item['content'], newsID, item['pic'], item['picDesc'])
        cur.execute(Sql_3, params_3)
        self.sqljapan.commit()

        # 下载新闻图片到本地文件夹
        if item['pic'] != "无图片":
            file_name = str(newsID)
            fname = time.strftime("%Y%m%d", time.localtime())
            filepath = r"C:/Users/张学友/Desktop/JapanPIC/" + fname #按照日期分图片
            if not os.path.exists(filepath):
                 os.mkdir(filepath)
            picpath = filepath + '/%s.jpg' % file_name
            p = pathlib.Path(picpath)
            if not p.exists():
                 urllib.request.urlretrieve(item['pic'], picpath)
                 print(picpath, "download completed")
            else:
                 print(picpath, "been completed")    



# 断开连接
def __del__(self):
    self.sqljapan.close()

到这里爬虫文件基本上就结束了,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值