1. 如何用python爬蟲抓取網頁內容
首先,你要安裝requests和BeautifulSoup4,然後執行如下代碼.
importrequests
frombs4importBeautifulSoup
iurl='http://news.sina.com.cn/c/nd/2017-08-03/doc-ifyitapp0128744.shtml'
res=requests.get(iurl)
res.encoding='utf-8'
#print(len(res.text))
soup=BeautifulSoup(res.text,'html.parser')
#標題
H1=soup.select('#artibodyTitle')[0].text
#來源
time_source=soup.select('.time-source')[0].text
#來源
origin=soup.select('#artibodyp')[0].text.strip()
#原標題
oriTitle=soup.select('#artibodyp')[1].text.strip()
#內容
raw_content=soup.select('#artibodyp')[2:19]
content=[]
forparagraphinraw_content:
content.append(paragraph.text.strip())
'@'.join(content)
#責任編輯
ae=soup.select('.article-editor')[0].text
這樣就可以了
2. Python編程基礎之(五)Scrapy爬蟲框架
經過前面四章的學習,我們已經可以使用Requests庫、Beautiful Soup庫和Re庫,編寫基本的Python爬蟲程序了。那麼這一章就來學習一個專業的網路爬蟲框架--Scrapy。沒錯,是框架,而不是像前面介紹的函數功能庫。
Scrapy是一個快速、功能強大的網路爬蟲框架。
可能大家還不太了解什麼是框架,爬蟲框架其實是實現爬蟲功能的一個軟體結構和功能組件的集合。
簡而言之, Scrapy就是一個爬蟲程序的半成品,可以幫助用戶實現專業的網路爬蟲。
使用Scrapy框架,不需要你編寫大量的代碼,Scrapy已經把大部分工作都做好了,允許你調用幾句代碼便自動生成爬蟲程序,可以節省大量的時間。
當然,框架所生成的代碼基本是一致的,如果遇到一些特定的爬蟲任務時,就不如自己使用Requests庫搭建來的方便了。
PyCharm安裝
測試安裝:
出現框架版本說明安裝成功。
掌握Scrapy爬蟲框架的結構是使用好Scrapy的重中之重!
先上圖:
整個結構可以簡單地概括為: 「5+2」結構和3條數據流
5個主要模塊(及功能):
(1)控制所有模塊之間的數據流。
(2)可以根據條件觸發事件。
(1)根據請求下載網頁。
(1)對所有爬取請求進行調度管理。
(1)解析DOWNLOADER返回的響應--response。
(2)產生爬取項--scraped item。
(3)產生額外的爬取請求--request。
(1)以流水線方式處理SPIDER產生的爬取項。
(2)由一組操作順序組成,類似流水線,每個操作是一個ITEM PIPELINES類型。
(3)清理、檢查和查重爬取項中的HTML數據並將數據存儲到資料庫中。
2個中間鍵:
(1)對Engine、Scheler、Downloader之間進行用戶可配置的控制。
(2)修改、丟棄、新增請求或響應。
(1)對請求和爬取項進行再處理。
(2)修改、丟棄、新增請求或爬取項。
3條數據流:
(1):圖中數字 1-2
1:Engine從Spider處獲得爬取請求--request。
2:Engine將爬取請求轉發給Scheler,用於調度。
(2):圖中數字 3-4-5-6
3:Engine從Scheler處獲得下一個要爬取的請求。
4:Engine將爬取請求通過中間件發送給Downloader。
5:爬取網頁後,Downloader形成響應--response,通過中間件發送給Engine。
6:Engine將收到的響應通過中間件發送給Spider處理。
(3):圖中數字 7-8-9
7:Spider處理響應後產生爬取項--scraped item。
8:Engine將爬取項發送給Item Pipelines。
9:Engine將爬取請求發送給Scheler。
任務處理流程:從Spider的初始爬取請求開始爬取,Engine控制各模塊數據流,不間斷從Scheler處獲得爬取請求,直至請求為空,最後到Item Pipelines存儲數據結束。
作為用戶,只需配置好Scrapy框架的Spider和Item Pipelines,也就是數據流的入口與出口,便可完成一個爬蟲程序的搭建。Scrapy提供了簡單的爬蟲命令語句,幫助用戶一鍵配置剩餘文件,那我們便來看看有哪些好用的命令吧。
Scrapy採用命令行創建和運行爬蟲
PyCharm打開Terminal,啟動Scrapy:
Scrapy基本命令行格式:
具體常用命令如下:
下面用一個例子來學習一下命令的使用:
1.建立一個Scrapy爬蟲工程,在已啟動的Scrapy中繼續輸入:
執行該命令,系統會在PyCharm的工程文件中自動創建一個工程,命名為pythonDemo。
2.產生一個Scrapy爬蟲,以教育部網站為例http://www.moe.gov.cn:
命令生成了一個名為demo的spider,並在Spiders目錄下生成文件demo.py。
命令僅用於生成demo.py文件,該文件也可以手動生成。
觀察一下demo.py文件:
3.配置產生的spider爬蟲,也就是demo.py文件:
4.運行爬蟲,爬取網頁:
如果爬取成功,會發現在pythonDemo下多了一個t20210816_551472.html的文件,我們所爬取的網頁內容都已經寫入該文件了。
以上就是Scrapy框架的簡單使用了。
Request對象表示一個HTTP請求,由Spider生成,由Downloader執行。
Response對象表示一個HTTP響應,由Downloader生成,有Spider處理。
Item對象表示一個從HTML頁面中提取的信息內容,由Spider生成,由Item Pipelines處理。Item類似於字典類型,可以按照字典類型來操作。
3. python網路爬蟲具體是怎樣的
舉一個例子來類比一下,在每日的新冠核酸排查時,發現了幾個陽性人員(種子地址),這時候會對每個陽性人員接觸的人員(地址內容)進行排查,對排查出的陽性人員再進行上面的接觸人員排查,層層排查,直到排查出所有陽悉攔性人員。
python網路爬蟲跟上面的例子很相似,
首先一批種子地址開始,將這些種子地址加入待處理的任務隊列;任務處理者從上面的任務隊列中取出一個地址,取出後需要將這個地址從任賀擾務隊列中移除,同時還要加到已處理地址字典中去,訪問地址獲取數據;處理上面獲取的數據,比如可能是一個網頁,網頁中又可能存在多個地址,比如一個頁面中又很多鏈接地址,將這些地址如果不在已處理的地址字典的話,就加入到待處理的任務隊列。同時提取獲取到的數據中的有禪陸旦用部分存儲下來;周而復始地執行上面2,3步操作,直到待處理地址隊列處理完,或者獲取了到了足夠數量的數據等結束條件。最後對採集到的有用數據就可以進行清洗,轉化處理,作為爬蟲的最後數據輸出。
4. 如何用Python做爬蟲
1)首先你要明白爬蟲怎樣工作。
想像你是一隻蜘蛛,現在你被放到了互聯「網」上。那麼,你需要把所有的網頁都看一遍。怎麼辦呢?沒問題呀,你就隨便從某個地方開始,比如說人民日報的首頁,這個叫initial pages,用$表示吧。
在人民日報的首頁,你看到那個頁面引向的各種鏈接。於是你很開心地從爬到了「國內新聞」那個頁面。太好了,這樣你就已經爬完了倆頁面(首頁和國內新聞)!暫且不用管爬下來的頁面怎麼處理的,你就想像你把這個頁面完完整整抄成了個html放到了你身上。
突然你發現, 在國內新聞這個頁面上,有一個鏈接鏈回「首頁」。作為一隻聰明的蜘蛛,你肯定知道你不用爬回去的吧,因為你已經看過了啊。所以,你需要用你的腦子,存下你已經看過的頁面地址。這樣,每次看到一個可能需要爬的新鏈接,你就先查查你腦子里是不是已經去過這個頁面地址。如果去過,那就別去了。
好的,理論上如果所有的頁面可以從initial page達到的話,那麼可以證明你一定可以爬完所有的網頁。
那麼在python里怎麼實現呢?
很簡單
import Queue
initial_page = "初始化頁"
url_queue = Queue.Queue()
seen = set()
seen.insert(initial_page)
url_queue.put(initial_page)
while(True): #一直進行直到海枯石爛
if url_queue.size()>0:
current_url = url_queue.get() #拿出隊例中第一個的url
store(current_url) #把這個url代表的網頁存儲好
for next_url in extract_urls(current_url): #提取把這個url里鏈向的url
if next_url not in seen:
seen.put(next_url)
url_queue.put(next_url)
else:
break
寫得已經很偽代碼了。
所有的爬蟲的backbone都在這里,下面分析一下為什麼爬蟲事實上是個非常復雜的東西——搜索引擎公司通常有一整個團隊來維護和開發。
2)效率
如果你直接加工一下上面的代碼直接運行的話,你需要一整年才能爬下整個豆瓣的內容。更別說Google這樣的搜索引擎需要爬下全網的內容了。
問題出在哪呢?需要爬的網頁實在太多太多了,而上面的代碼太慢太慢了。設想全網有N個網站,那麼分析一下判重的復雜度就是N*log(N),因為所有網頁要遍歷一次,而每次判重用set的話需要log(N)的復雜度。OK,OK,我知道python的set實現是hash——不過這樣還是太慢了,至少內存使用效率不高。
通常的判重做法是怎樣呢?Bloom Filter. 簡單講它仍然是一種hash的方法,但是它的特點是,它可以使用固定的內存(不隨url的數量而增長)以O(1)的效率判定url是否已經在set中。可惜天下沒有白吃的午餐,它的唯一問題在於,如果這個url不在set中,BF可以100%確定這個url沒有看過。但是如果這個url在set中,它會告訴你:這個url應該已經出現過,不過我有2%的不確定性。注意這里的不確定性在你分配的內存足夠大的時候,可以變得很小很少。一個簡單的教程:Bloom Filters by Example
注意到這個特點,url如果被看過,那麼可能以小概率重復看一看(沒關系,多看看不會累死)。但是如果沒被看過,一定會被看一下(這個很重要,不然我們就要漏掉一些網頁了!)。 [IMPORTANT: 此段有問題,請暫時略過]
好,現在已經接近處理判重最快的方法了。另外一個瓶頸——你只有一台機器。不管你的帶寬有多大,只要你的機器下載網頁的速度是瓶頸的話,那麼你只有加快這個速度。用一台機子不夠的話——用很多台吧!當然,我們假設每台機子都已經進了最大的效率——使用多線程(python的話,多進程吧)。
3)集群化抓取
爬取豆瓣的時候,我總共用了100多台機器晝夜不停地運行了一個月。想像如果只用一台機子你就得運行100個月了...
那麼,假設你現在有100台機器可以用,怎麼用python實現一個分布式的爬取演算法呢?
我們把這100台中的99台運算能力較小的機器叫作slave,另外一台較大的機器叫作master,那麼回顧上面代碼中的url_queue,如果我們能把這個queue放到這台master機器上,所有的slave都可以通過網路跟master聯通,每當一個slave完成下載一個網頁,就向master請求一個新的網頁來抓取。而每次slave新抓到一個網頁,就把這個網頁上所有的鏈接送到master的queue里去。同樣,bloom filter也放到master上,但是現在master只發送確定沒有被訪問過的url給slave。Bloom Filter放到master的內存里,而被訪問過的url放到運行在master上的Redis里,這樣保證所有操作都是O(1)。(至少平攤是O(1),Redis的訪問效率見:LINSERT – Redis)
考慮如何用python實現:
在各台slave上裝好scrapy,那麼各台機子就變成了一台有抓取能力的slave,在master上裝好Redis和rq用作分布式隊列。
代碼於是寫成
#slave.py
current_url = request_from_master()
to_send = []
for next_url in extract_urls(current_url):
to_send.append(next_url)
store(current_url);
send_to_master(to_send)
#master.py
distributed_queue = DistributedQueue()
bf = BloomFilter()
initial_pages = "www.renmingribao.com"
while(True):
if request == 'GET':
if distributed_queue.size()>0:
send(distributed_queue.get())
else:
break
elif request == 'POST':
bf.put(request.url)
好的,其實你能想到,有人已經給你寫好了你需要的:darkrho/scrapy-redis · GitHub
4)展望及後處理
雖然上面用很多「簡單」,但是真正要實現一個商業規模可用的爬蟲並不是一件容易的事。上面的代碼用來爬一個整體的網站幾乎沒有太大的問題。
但是如果附加上你需要這些後續處理,比如
有效地存儲(資料庫應該怎樣安排)
有效地判重(這里指網頁判重,咱可不想把人民日報和抄襲它的大民日報都爬一遍)
有效地信息抽取(比如怎麼樣抽取出網頁上所有的地址抽取出來,「朝陽區奮進路中華道」),搜索引擎通常不需要存儲所有的信息,比如圖片我存來幹嘛...
及時更新(預測這個網頁多久會更新一次)
如你所想,這里每一個點都可以供很多研究者十數年的研究。雖然如此,
「路漫漫其修遠兮,吾將上下而求索」。
所以,不要問怎麼入門,直接上路就好了:)
5. python爬蟲怎麼做
大到各類搜索引擎,小到日常數據採集,都離不開網路爬蟲。爬蟲的基本原理很簡單,遍歷網路中網頁,抓取感興趣的數據內容。這篇文章會從零開始介紹如何編寫一個網路爬蟲抓取數據做告宏,然後會一步步逐漸完善爬蟲的抓取功能。
工具安裝
我們需要安裝python,python的requests和BeautifulSoup庫。我們用Requests庫用抓取網頁的內容,使用BeautifulSoup庫來從網頁中提取數據。
安裝python
運行pipinstallrequests
運行pipinstallBeautifulSoup
抓取網頁
完成必要工具安裝後,我們正式開始編寫我們的爬蟲。我們的第一個任務是要抓取所有豆瓣上的圖書信息。我們以/subject/26986954/為例,首先看看開如何抓取網頁的內容。
使用python的requests提供的get()方法我們可以非常簡單的獲取的指定網頁的內純冊容,代碼如下:
提取內容
抓取到網頁的內容後,我們要做的就是提取出我們想要的內容。在我們的第一個例子中,我們只需要提取書名。首先我們導入BeautifulSoup庫,使用BeautifulSoup我們可以非常簡單的提取網頁的特定內容。
連續抓取網頁
到目前為止,我們已經可以抓取單個網頁的內容了,現在讓我們看看如何抓取整個網站的內容。我們知道網頁之間是通過超鏈接互相連接在一起的,通過鏈接我們可以訪問整個網路。所以我們可以從每個頁面提取出包含指向其它網頁的鏈接,然後重復的對新鏈接進行抓取。
通過以上幾步我們就可以寫出一個最原始的爬蟲。在理解了爬蟲原理的基礎上,我們可以進一步對爬蟲進行完善。
寫過一個系列關於爬蟲的文章:/i6567289381185389064/。感興趣的可以前往查看。
Python基本環境的搭建,爬蟲的基本原理以及爬蟲的原型
Python爬蟲入門(第1部分)
如何使用BeautifulSoup對網頁內容進行提取
Python爬蟲入門(第2部分)
爬蟲運行時數據的存儲數據,以SQLite和MySQL作為示例
Python爬蟲入門(第3部分)
使用seleniumwebdriver對動態網頁進行抓取
Python爬蟲入門(第4部分)
討論了如何處理網站的反爬蟲策略
Python爬友如蟲入門(第5部分)
對Python的Scrapy爬蟲框架做了介紹,並簡單的演示了如何在Scrapy下進行開發
Python爬蟲入門(第6部分)
6. python怎麼看源碼進行網路爬蟲
在我們日常上網瀏覽網頁的時候,經常會看到一些好看的圖片,我們就希望把這些圖片保存下載,或者用戶用來做桌面壁紙,或者用來做設計的素材。
我們最常規的做法就是通過滑鼠右鍵,選擇另存為。但有些圖片滑鼠右鍵的時候並沒有另存為選項,還有辦法就通過就是通過截圖工具截取下來,但這樣就降低圖片的清晰度。好吧~!其實你很厲害的,右鍵查看頁面源代碼。
我們可以通過python 來實現這樣一個簡單的爬蟲功能,把我們想要的代碼爬取到本地。下面就看看如何使用python來實現這樣一個功能。
一,獲取整個頁面數據
首先我們可以先獲取要下載圖片的整個頁面信息。
getjpg.py
#coding=utf-8
import urllib
def getHtml(url):
page = urllib.urlopen(url)
html = page.read()
return html
html = getHtml("http://tieba..com/p/2738151262")
print html
Urllib 模塊提供了讀取web頁面數據的介面,我們可以像讀取本地文件一樣讀取www和ftp上的數據。首先,我們定義了一個getHtml()函數:
urllib.urlopen()方法用於打開一個URL地址。
read()方法用於讀取URL上的數據,向getHtml()函數傳遞一個網址,並把整個頁面下載下來。執行程序就會把整個網頁列印輸出。
二,篩選頁面中想要的數據
Python 提供了非常強大的正則表達式,我們需要先要了解一點python 正則表達式的知識才行。
http://www.cnblogs.com/fnng/archive/2013/05/20/3089816.html
假如我們網路貼吧找到了幾張漂亮的壁紙,通過到前段查看工具。找到了圖片的地址,如:src=」https://gss0..com/70cFfyinKgQFm2e88IuM_a/forum......jpg」pic_ext=」jpeg」
修改代碼如下:
import re
import urllib
def getHtml(url):
page = urllib.urlopen(url)
html = page.read()
return html
def getImg(html):
reg = r'src="(.+?\.jpg)" pic_ext'
imgre = re.compile(reg)
imglist = re.findall(imgre,html)
return imglist
html = getHtml("http://tieba..com/p/2460150866")
print getImg(html)
我們又創建了getImg()函數,用於在獲取的整個頁面中篩選需要的圖片連接。re模塊主要包含了正則表達式:
re.compile() 可以把正則表達式編譯成一個正則表達式對象.
re.findall() 方法讀取html 中包含 imgre(正則表達式)的數據。
運行腳本將得到整個頁面中包含圖片的URL地址。
三,將頁面篩選的數據保存到本地
把篩選的圖片地址通過for循環遍歷並保存到本地,代碼如下:
#coding=utf-8
import urllib
import re
def getHtml(url):
page = urllib.urlopen(url)
html = page.read()
return html
def getImg(html):
reg = r'src="(.+?\.jpg)" pic_ext'
imgre = re.compile(reg)
imglist = re.findall(imgre,html)
x = 0
for imgurl in imglist:
urllib.urlretrieve(imgurl,'%s.jpg' % x)
x+=1
html = getHtml("http://tieba..com/p/2460150866")
print getImg(html)
這里的核心是用到了urllib.urlretrieve()方法,直接將遠程數據下載到本地。
通過一個for循環對獲取的圖片連接進行遍歷,為了使圖片的文件名看上去更規范,對其進行重命名,命名規則通過x變數加1。保存的位置默認為程序的存放目錄。
程序運行完成,將在目錄下看到下載到本地的文件。
7. 用python爬取關鍵詞並解釋
Copyright © 1999-2020, CSDN.NET, All Rights Reserved
python
打開APP
小羊努力搞代碼
關注
學習日誌:Python 實現網路爬蟲——提取關鍵字 原創
2022-06-19 13:02:38
小羊努力搞代碼
碼齡174天
關注
編寫一段Python代碼,向網路提交查詢關鍵詞「桃花源記」,抓取網路的查詢結果,要求有文字、鏈接,可以在瀏覽器中打開抓取的鏈接,或者調用瀏覽器打開抓取的鏈接。
紅框內是根據網站信息需要更改的內容。.png
附上完整代碼:
import json
import requests
from lxml import etree
headers = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/88.0.4324.104 Safari/537.36"
}
response = requests.get('https://www..com/s?wd=桃花源記&lm=0', headers=headers)
r = response.text
html = etree.HTML(r, etree.HTMLParser())
r1 = html.xpath('//h3')
r2 = html.xpath('//*[@class="content-right_8Zs40"]')
r3 = html.xpath('//*[@class="c-row source_1Vdff OP_LOG_LINK c-gap-top-xsmall"]/a/@href')
for i in range(4):
r11 = r1[i].xpath('string(.)')
r22 = r2[i].xpath('string(.)')
r33 = r3[i]
with open('桃花源記.txt', 'a', encoding='utf-8') as c:
c.write(json.mps(r11,ensure_ascii=False) + '\n')
c.write(json.mps(r22, ensure_ascii=False) + '\n')
c.write(json.mps(r33, ensure_ascii=False) + '\n')
print(r11, end='\n')
print('------------------------')
print(r22, end='\n')
print(r33)