日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Scrapy框架爬取百度新闻

發(fā)布時(shí)間:2024/8/1 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Scrapy框架爬取百度新闻 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 一、前期準(zhǔn)備
  • 二、初識(shí)Scrapy
  • 三、網(wǎng)頁分析(重點(diǎn)&難點(diǎn))
  • 四、代碼編寫
  • 五、結(jié)果展示

本次博客使用 Scrapy爬蟲框架 爬取 百度新聞,并保存到 Mysql數(shù)據(jù)庫 中。除了知道爬蟲知識(shí)外,還需要了解一下數(shù)據(jù)庫的知識(shí)。

如果你不太了解數(shù)據(jù)庫的知識(shí),請(qǐng)你不要慌,看我的Mysql系列博客就好啦…(雖然是轉(zhuǎn)載,但也是我一個(gè)字一個(gè)字敲的,都是經(jīng)過大腦和驗(yàn)證的)

一、前期準(zhǔn)備

  • 會(huì)簡(jiǎn)單使用Fidder進(jìn)行抓包;
  • 會(huì)一點(diǎn)Scrapy爬蟲框架(網(wǎng)上教程很多,也可看我第二章內(nèi)容);
  • 會(huì)一點(diǎn)簡(jiǎn)單的數(shù)據(jù)庫操作(建庫、建表、增刪查改)

二、初識(shí)Scrapy

工欲善其事必先利其器,Scrapy框架的安裝,請(qǐng)看我這篇博客 (傳送門), 里面詳細(xì)且正確的告訴大家如何安裝Scrapy框架。

安裝好Scrapy框架后,我們?cè)撊绾问褂盟?#xff1f;下面我會(huì)簡(jiǎn)單介紹幾個(gè)Scrapy框架常用的命令。知道了這些命令,我們就能創(chuàng)建并運(yùn)行爬蟲項(xiàng)目了。

  • startproject命令
  • genspider命令
  • crawl命令

注意:這些命令都是在cmd中操作,且是以管理員身份打開

1、startproject命令

語法:

scrapy startproject 爬蟲項(xiàng)目名

我們可以通過這個(gè)命令創(chuàng)建一個(gè)Scrapy框架爬蟲項(xiàng)目,如下:

說明:

  • D:\pythonProgram\scrapytest1路徑 是創(chuàng)建存放爬蟲項(xiàng)目的文件夾的路徑。這個(gè)文件夾在何處創(chuàng)建,讀者隨意;
  • scrapy startprojct 是固定搭配,scrapy是Scrapy框架中每個(gè)命令必帶的前綴;
  • newsbaidu 是爬蟲項(xiàng)目名

創(chuàng)建完之后,我們可以去此路徑查看一下,如下:

2、genspider命令

語法:

scrapy genspider -t 爬蟲文件模板 爬蟲文件名 域名

我們可以通過這個(gè)命令創(chuàng)建一個(gè)爬蟲文件,注意,是創(chuàng)建爬蟲文件。前面那個(gè)startprojct命令是創(chuàng)建爬蟲項(xiàng)目,一個(gè)項(xiàng)目里面可有多個(gè)爬蟲文件。

在Scrapy框架中,其為我們提供了四個(gè)爬蟲文件模板,我們可以在cmd中輸入 scrapy genspider -l(這里是小寫的l,不是數(shù)字1),如下:

一般的爬蟲項(xiàng)目,我們使用basic模板創(chuàng)建爬蟲文件即可,其它3個(gè)模板,如需求,請(qǐng)讀者自行了解!

創(chuàng)建爬蟲文件,如下:

說明:

  • cd newsbaidu:創(chuàng)建爬蟲文件前,需先進(jìn)入爬蟲項(xiàng)目;
  • scrapy genspider -t:是創(chuàng)建爬蟲文件模板的固定搭配;
  • basic:爬蟲文件模板
  • news:項(xiàng)目里的爬蟲文件名
  • baidu.com:要爬取網(wǎng)站的域名

3、crawl命令

語法:

# 顯示爬取日志 scrapy crawl 爬蟲文件名 或 # 不顯示爬取日志 scrapy crawl 爬蟲文件名 --nolog

這個(gè)命令的作用是運(yùn)行爬蟲文件,進(jìn)行網(wǎng)頁數(shù)據(jù)爬取。現(xiàn)在還未編寫爬蟲文件,需等到最后運(yùn)行爬蟲文件時(shí),再演示。

4、簡(jiǎn)析項(xiàng)目文件結(jié)構(gòu)


從上往下,逐一簡(jiǎn)單介紹:

  • newsbaidu:項(xiàng)目名稱
  • spiders:爬蟲主程序腳本文件夾
  • news.py:爬蟲腳本文件,數(shù)據(jù)爬取主要在此
  • items.py:指定保存文件的數(shù)據(jù)結(jié)構(gòu),即數(shù)據(jù)的封裝實(shí)體類
  • middlewares.py:中間件,處理request和reponse等相關(guān)配置
  • pipelines.py:項(xiàng)目管道文件,可對(duì)采集后數(shù)據(jù)的進(jìn)行處理
  • settings.py:設(shè)置文件,指定項(xiàng)目的一些配置
  • scrapy.cfg:配置文件,指定路徑

我們主要操作的文件,就是上面加粗的文件。

三、網(wǎng)頁分析(重點(diǎn)&難點(diǎn))

1、簡(jiǎn)單分析網(wǎng)頁

打開瀏覽器進(jìn)入百度新聞首頁,如下:

復(fù)制 “讓城市留在記憶,讓人們記住鄉(xiāng)愁”,進(jìn)入首頁源代碼查看是否存在這句話,如下:

發(fā)現(xiàn)有這句話。我們進(jìn)行第一個(gè)猜測(cè):可能全部的新聞標(biāo)題和新聞url都在首頁源代碼中。為了驗(yàn)證這個(gè)猜測(cè),我們?cè)龠x擇首頁中的一句話 “伊朗宣布將于周五開始與中俄軍演,為伊斯蘭革命后首次”,進(jìn)入首頁源代碼查看是否存在,如下:


經(jīng)過幾次上面的操作,我們發(fā)現(xiàn):除了熱點(diǎn)要聞可以在首頁源代碼都查詢,其他都不能 。這個(gè)時(shí)候,我們可能要想一下,百度新聞中其他新聞標(biāo)題和url信息是不是 通過JS的Ajax異步請(qǐng)求生成的呢 ?下面我們就通過Fiddler抓包分析。

2、Fiddler抓包分析

前面 :我使用的是谷歌瀏覽器,所以要想用Fidder進(jìn)行抓包分析,除了下載一個(gè)Fiddler軟件,還需要給谷歌瀏覽器安裝一個(gè)SwitchyOmega插件,怎么在谷歌下載和安裝這個(gè)插件,請(qǐng)自行百度啦(不然跑題了…)。使用火狐瀏覽器的朋友呢,不用下載這個(gè)插件,可以在瀏覽器里面直接配置,也請(qǐng)自行百度啦。

(1)打開Fiddler軟件

(一個(gè)小技巧:在刷新頁面之前,Fiddler里面就開始不知道抓些什么包了,我們可以在底下輸入:clear,清除掉這些記錄哦!)

(2)在谷歌瀏覽器里面刷新百度新聞頁面

刷新完頁面后,我們進(jìn)入Fiddler,它已經(jīng)為我們抓了很多包了,接下來要靠我們自己了。這里也有小技巧吶:如果我們前面分析出,數(shù)據(jù)可能存放在JS文件中,我們肯定要特別關(guān)照一下下Fiddler抓的JS文件了。請(qǐng)看下圖:

這顯示的是什么鬼??是人看的嗎?! 這當(dāng)然不是人看的了,我們可以復(fù)制里面的Unicode編碼,借助Python自帶的編輯器IDLE,將其轉(zhuǎn)碼,我們?nèi)嗽倏础H缦?#xff1a;


原來那串Unicode編碼是這個(gè)意思,真有意思啊。我們復(fù)制這句話到百度新聞首頁找找,如下:

嘿!還真找到了。我們進(jìn)行第二個(gè)猜測(cè):數(shù)據(jù)都存放在這個(gè)JS文件里面。我們就再去Fiddler里面觀察一下這個(gè)JS文件,發(fā)現(xiàn)好像不太對(duì),這里面的數(shù)據(jù)一看明顯就太少了,和百度新聞首頁里面那么多新聞數(shù)據(jù)完全不是一個(gè)數(shù)量級(jí)別。難道?數(shù)據(jù)還存放在其他JS文件中?就再去Fiddler里面找其他JS文件…(讀者,你先去找吧…任你找,找破天也不會(huì)找的,哈哈哈哈哈)

好像找不到了,其他JS文件夾里面沒有數(shù)據(jù)啊…我再重新刷新一下百度新聞頁面,說不定會(huì)出來。刷啊刷啊,找啊找啊,還是沒的。

這個(gè)時(shí)候,我們好像束手無策。別急,我們百度一下,看以前有沒有人分析過百度新聞,看他們?cè)趺凑业揭?guī)律的。百度了一下,好像、貌似沒有…(如果有,也請(qǐng)讀者好好琢磨琢磨,他們是怎么找到規(guī)律的!)

我們就盯著有數(shù)據(jù)的JS文件看,進(jìn)行天馬行空的想象了。我們觀察到JS的url好像有點(diǎn)古怪,如下:

好像,有數(shù)據(jù)的JS文件的url和底下那幾個(gè)比較顯眼的綠色的get請(qǐng)求文件的url有那么一丟丟的類似。如果英文水平還行,應(yīng)該可以看懂箭頭指向的單詞是什么意思。然后,再對(duì)比一下百度新聞首頁中的新聞?lì)悇e,我們好像發(fā)現(xiàn)了一點(diǎn)什么!!

復(fù)制這些文件的url(對(duì)著這個(gè)文件,右擊 > Copy > Just Url),進(jìn)行對(duì)比和測(cè)試,如下:

經(jīng)過對(duì)比和測(cè)試這些url,我們可以發(fā)現(xiàn):

  • 每個(gè)url后面的 t=1579xxxxxxx,應(yīng)該是時(shí)間戳,刪除也不會(huì)對(duì)進(jìn)入url有影響;
  • 除了本地新聞的url還多一串:&ajax=json,我們進(jìn)行測(cè)試,這個(gè)代表JSON格式,為其他url后面加上這個(gè)字符串,也都從html網(wǎng)頁格式變成了JSON格式。

有了這些新聞的JSON數(shù)據(jù)格式,接下來就是分析正則表達(dá)式,提取我們想要的數(shù)據(jù)了。

  • 對(duì)本地新聞,標(biāo)題正則表達(dá)式:“title”:"(.*?)";url正則表達(dá)式:“url”:"(.*?)"
  • 對(duì)其他新聞,標(biāo)題正則表達(dá)式:“m_title”:"(.*?)";url正則表達(dá)式:“m_url”:"(.*?)"

分析,我們就到此結(jié)束。如有疑問,請(qǐng)多多練習(xí)!

四、代碼編寫

1、爬蟲項(xiàng)目創(chuàng)建(先在cmd中)

2、數(shù)據(jù)庫表的創(chuàng)建

3、爬蟲代碼編寫

(1)進(jìn)入Pycharm,導(dǎo)入爬蟲項(xiàng)目newsbaidu

File > Open >

(2)設(shè)置配置文件settings.py



(3)item.py編寫

(4)編寫news.py

# -*- coding: utf-8 -*- import scrapy import re from scrapy.http import Request from newsbaidu.items import NewsbaiduItemclass NewsSpider(scrapy.Spider):name = 'news'# 域名allowed_domains = ['baidu.com']# 爬取開始網(wǎng)址start_urls = ['https://news.baidu.com/widget?id=LocalNews&ajax=json']# 百度新聞?lì)悇eallid = ['LocalNews', 'civilnews', 'InternationalNews', 'EnterNews', 'SportNews', 'FinanceNews', 'TechNews','MilitaryNews', 'InternetNews', 'DiscoveryNews', 'LadyNews', 'HealthNews', 'PicWall']# 構(gòu)造百度新聞網(wǎng)址allurl = []for url in range(0, len(allid)):thisid = allid[url]thisurl = "https://news.baidu.com/widget?id=" + thisid + "&ajax=json"allurl.append(thisurl)def parse(self, response):for i in range(0, len(self.allurl)):print("第" + str(i) + "個(gè)欄目")print("爬取網(wǎng)址:" + self.allurl[i])yield Request(self.allurl[i], callback=self.next)"""某個(gè)新聞模塊數(shù)據(jù)爬取"""def next(self, response):print("進(jìn)入next方法")# 進(jìn)入本地新聞if (response.url == 'https://news.baidu.com/widget?id=LocalNews&ajax=json'):data = response.body.decode("utf-8", "ignore")alldata = self.get_data(data, self.pattern(1))else: # 進(jìn)入其他新聞data = response.body.decode("utf-8", "ignore")alldata = self.get_data(data, self.pattern(2))# 創(chuàng)建BaidunewsItem對(duì)象item = NewsbaiduItem()item["title"] = alldata[0]item["link"] = alldata[1]yield item# 用于正則表達(dá)式的匹配def pattern(self, choice):# 存放正則表達(dá)式pattern = []if (choice == 1):# 編寫正則表達(dá)式pat1 = '"title":"(.*?)"'pat2 = '"url":"(.*?)"'pattern.append(pat1)pattern.append(pat2)elif (choice == 2):# 編寫正則表達(dá)式pat1 = '"m_title":"(.*?)"'pat2 = '"m_url":"(.*?)"'pattern.append(pat1)pattern.append(pat2)return pattern'''處理本地新聞數(shù)據(jù),獲取新聞標(biāo)題和url'''def get_data(self, data, pattern):print("調(diào)用了get_data1方法")# 編寫正則表達(dá)式pat1 = pattern[0]pat2 = pattern[1]# 爬取網(wǎng)頁數(shù)據(jù)里面的新聞標(biāo)題titledata = re.compile(pat1, re.S).findall(data)# 爬取網(wǎng)頁數(shù)據(jù)里面的url數(shù)據(jù)urldata = re.compile(pat2, re.S).findall(data)# 存放新聞標(biāo)題titilall = []# 存放新聞urlurlall = []for i in range(0, len(titledata)):# 轉(zhuǎn)碼,顯示成中文——這步只是為了調(diào)試方便thistitle = re.sub(r'(\\u[\s\S]{4})', lambda x: x.group(1).encode("utf-8").decode("unicode-escape"),titledata[i])titilall.append(thistitle)# 處理url,用/替換\/for j in range(0, len(urldata)):thisurl = re.sub("\\\/", "/", urldata[j])urlall.append(thisurl)# 存放新聞標(biāo)題和urlalldata = []alldata.append(titilall)alldata.append(urlall)return self.deal_data(alldata)# 處理新聞標(biāo)題和新聞url,使其一一對(duì)應(yīng)def deal_data(self, alldata):print("進(jìn)入deal_data方法")# 判斷新聞標(biāo)題和url是否一一對(duì)應(yīng)if (len(alldata[0]) == len(alldata[1])):return alldataelse: # 根據(jù)源碼分析,我們可以得知:都是新聞標(biāo)題比url多,我們只要從前刪除標(biāo)題直到標(biāo)題數(shù)量與url數(shù)量相等時(shí)即可# 首先求出新聞標(biāo)題比新聞url多幾個(gè)count_url = len(alldata[0]) - len(alldata[1])for i in range(0, count_url):alldata[0].pop(0)return alldata

5、編寫pipelines.py

把數(shù)據(jù)出入數(shù)據(jù)庫中。

# -*- coding: utf-8 -*- import pymysql # Define your item pipelines here # # Don't forget to add your pipeline to the ITEM_PIPELINES setting # See: https://docs.scrapy.org/en/latest/topics/item-pipeline.htmlclass NewsbaiduPipeline(object):def process_item(self, item, spider):# 連接數(shù)據(jù)庫conn = pymysql.connect(host="localhost",user="root",passwd="ydjws",db="test",port=3306,charset="utf8",)# 游標(biāo)cur = conn.cursor()for i in range(0, len(item["title"])):title = item["title"][i]link = item["link"][i]# 編寫sql語句sql = "insert into t_news(title,link) values ('" + title + "','" + link + "')"try:cur.execute(sql)conn.commit()except Exception as err:print(err)conn.rollback()conn.close()return item

五、結(jié)果展示

1、執(zhí)行scrapy crawl news --nolog


2、查看數(shù)據(jù)庫

總結(jié)

以上是生活随笔為你收集整理的Scrapy框架爬取百度新闻的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。