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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Scrapy框架爬取百度新闻

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

文章目錄

  • 一、前期準備
  • 二、初識Scrapy
  • 三、網頁分析(重點&難點)
  • 四、代碼編寫
  • 五、結果展示

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

如果你不太了解數據庫的知識,請你不要慌,看我的Mysql系列博客就好啦…(雖然是轉載,但也是我一個字一個字敲的,都是經過大腦和驗證的)

一、前期準備

  • 會簡單使用Fidder進行抓包;
  • 會一點Scrapy爬蟲框架(網上教程很多,也可看我第二章內容);
  • 會一點簡單的數據庫操作(建庫、建表、增刪查改)

二、初識Scrapy

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

安裝好Scrapy框架后,我們該如何使用它呢?下面我會簡單介紹幾個Scrapy框架常用的命令。知道了這些命令,我們就能創建并運行爬蟲項目了。

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

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

1、startproject命令

語法:

scrapy startproject 爬蟲項目名

我們可以通過這個命令創建一個Scrapy框架爬蟲項目,如下:

說明:

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

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

2、genspider命令

語法:

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

我們可以通過這個命令創建一個爬蟲文件,注意,是創建爬蟲文件。前面那個startprojct命令是創建爬蟲項目,一個項目里面可有多個爬蟲文件。

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

一般的爬蟲項目,我們使用basic模板創建爬蟲文件即可,其它3個模板,如需求,請讀者自行了解!

創建爬蟲文件,如下:

說明:

  • cd newsbaidu:創建爬蟲文件前,需先進入爬蟲項目;
  • scrapy genspider -t:是創建爬蟲文件模板的固定搭配;
  • basic:爬蟲文件模板
  • news:項目里的爬蟲文件名
  • baidu.com:要爬取網站的域名

3、crawl命令

語法:

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

這個命令的作用是運行爬蟲文件,進行網頁數據爬取。現在還未編寫爬蟲文件,需等到最后運行爬蟲文件時,再演示。

4、簡析項目文件結構


從上往下,逐一簡單介紹:

  • newsbaidu:項目名稱
  • spiders:爬蟲主程序腳本文件夾
  • news.py:爬蟲腳本文件,數據爬取主要在此
  • items.py:指定保存文件的數據結構,即數據的封裝實體類
  • middlewares.py:中間件,處理request和reponse等相關配置
  • pipelines.py:項目管道文件,可對采集后數據的進行處理
  • settings.py:設置文件,指定項目的一些配置
  • scrapy.cfg:配置文件,指定路徑

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

三、網頁分析(重點&難點)

1、簡單分析網頁

打開瀏覽器進入百度新聞首頁,如下:

復制 “讓城市留在記憶,讓人們記住鄉愁”,進入首頁源代碼查看是否存在這句話,如下:

發現有這句話。我們進行第一個猜測:可能全部的新聞標題和新聞url都在首頁源代碼中。為了驗證這個猜測,我們再選擇首頁中的一句話 “伊朗宣布將于周五開始與中俄軍演,為伊斯蘭革命后首次”,進入首頁源代碼查看是否存在,如下:


經過幾次上面的操作,我們發現:除了熱點要聞可以在首頁源代碼都查詢,其他都不能 。這個時候,我們可能要想一下,百度新聞中其他新聞標題和url信息是不是 通過JS的Ajax異步請求生成的呢 ?下面我們就通過Fiddler抓包分析。

2、Fiddler抓包分析

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

(1)打開Fiddler軟件

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

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

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

這顯示的是什么鬼??是人看的嗎?! 這當然不是人看的了,我們可以復制里面的Unicode編碼,借助Python自帶的編輯器IDLE,將其轉碼,我們人再看。如下:


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

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

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

這個時候,我們好像束手無策。別急,我們百度一下,看以前有沒有人分析過百度新聞,看他們怎么找到規律的。百度了一下,好像、貌似沒有…(如果有,也請讀者好好琢磨琢磨,他們是怎么找到規律的!)

我們就盯著有數據的JS文件看,進行天馬行空的想象了。我們觀察到JS的url好像有點古怪,如下:

好像,有數據的JS文件的url和底下那幾個比較顯眼的綠色的get請求文件的url有那么一丟丟的類似。如果英文水平還行,應該可以看懂箭頭指向的單詞是什么意思。然后,再對比一下百度新聞首頁中的新聞類別,我們好像發現了一點什么!!

復制這些文件的url(對著這個文件,右擊 > Copy > Just Url),進行對比和測試,如下:

經過對比和測試這些url,我們可以發現:

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

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

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

分析,我們就到此結束。如有疑問,請多多練習!

四、代碼編寫

1、爬蟲項目創建(先在cmd中)

2、數據庫表的創建

3、爬蟲代碼編寫

(1)進入Pycharm,導入爬蟲項目newsbaidu

File > Open >

(2)設置配置文件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']# 爬取開始網址start_urls = ['https://news.baidu.com/widget?id=LocalNews&ajax=json']# 百度新聞類別allid = ['LocalNews', 'civilnews', 'InternationalNews', 'EnterNews', 'SportNews', 'FinanceNews', 'TechNews','MilitaryNews', 'InternetNews', 'DiscoveryNews', 'LadyNews', 'HealthNews', 'PicWall']# 構造百度新聞網址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) + "個欄目")print("爬取網址:" + self.allurl[i])yield Request(self.allurl[i], callback=self.next)"""某個新聞模塊數據爬取"""def next(self, response):print("進入next方法")# 進入本地新聞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: # 進入其他新聞data = response.body.decode("utf-8", "ignore")alldata = self.get_data(data, self.pattern(2))# 創建BaidunewsItem對象item = NewsbaiduItem()item["title"] = alldata[0]item["link"] = alldata[1]yield item# 用于正則表達式的匹配def pattern(self, choice):# 存放正則表達式pattern = []if (choice == 1):# 編寫正則表達式pat1 = '"title":"(.*?)"'pat2 = '"url":"(.*?)"'pattern.append(pat1)pattern.append(pat2)elif (choice == 2):# 編寫正則表達式pat1 = '"m_title":"(.*?)"'pat2 = '"m_url":"(.*?)"'pattern.append(pat1)pattern.append(pat2)return pattern'''處理本地新聞數據,獲取新聞標題和url'''def get_data(self, data, pattern):print("調用了get_data1方法")# 編寫正則表達式pat1 = pattern[0]pat2 = pattern[1]# 爬取網頁數據里面的新聞標題titledata = re.compile(pat1, re.S).findall(data)# 爬取網頁數據里面的url數據urldata = re.compile(pat2, re.S).findall(data)# 存放新聞標題titilall = []# 存放新聞urlurlall = []for i in range(0, len(titledata)):# 轉碼,顯示成中文——這步只是為了調試方便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)# 存放新聞標題和urlalldata = []alldata.append(titilall)alldata.append(urlall)return self.deal_data(alldata)# 處理新聞標題和新聞url,使其一一對應def deal_data(self, alldata):print("進入deal_data方法")# 判斷新聞標題和url是否一一對應if (len(alldata[0]) == len(alldata[1])):return alldataelse: # 根據源碼分析,我們可以得知:都是新聞標題比url多,我們只要從前刪除標題直到標題數量與url數量相等時即可# 首先求出新聞標題比新聞url多幾個count_url = len(alldata[0]) - len(alldata[1])for i in range(0, count_url):alldata[0].pop(0)return alldata

5、編寫pipelines.py

把數據出入數據庫中。

# -*- 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):# 連接數據庫conn = pymysql.connect(host="localhost",user="root",passwd="ydjws",db="test",port=3306,charset="utf8",)# 游標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

五、結果展示

1、執行scrapy crawl news --nolog


2、查看數據庫

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。