最近中文字幕2019高清,亚洲人成高清在线播放,男生淦哭男生图片动漫有字,国产亚洲精品九九久在线观看,无码av专区丝袜专区

使用代理處理反爬抓取陌陌文章

優(yōu)采云 發(fā)布時(shí)間: 2020-06-06 08:01

  使用代理反爬抓取陌陌文章,獲取文章標題、內容、公眾號等信息,并儲存到MongoDB數據庫中。

  如果要抓取微信公眾號文章可以使用搜狗的搜索引擎,它會(huì )顯示最新的文章,但是有兩個(gè)問(wèn)題須要你們注意:

  關(guān)于代理池的實(shí)現以及使用可以參考這篇文章:使用Redis+Flask維護動(dòng)態(tài)代理池

  下圖展示了具體的流程框架:

  /img/remote/36680

  def parse_index(html):

doc = pq(html)

items = doc('.news-box .news-list li .txt-box h3 a').items()

for item in items:

yield item.attr('href')def parse_index(html):

doc = pq(html)

items = doc('.news-box .news-list li .txt-box h3 a').items()

for item in items:

yield item.attr('href')

  在流程框架部份我們談到,在此即將使用搜狗搜索陌陌站點(diǎn)文章,首先使我們步入搜狗搜索界面,比如輸入關(guān)鍵字景色,就會(huì )出現陌陌文章的列表。

  /img/remote/36681?w=1042&h=552

  從網(wǎng)頁(yè)的url可以看出這是一個(gè)get懇求,只保留主要參數,可以把url簡(jiǎn)化為

  /img/remote/36682

  其中,“query”代表搜索的關(guān)鍵詞,“type”代表搜索結果的類(lèi)型,“type=1”表示搜索結果是微信公眾號,“type=2”表示搜索結果是陌陌文章,“page”也就是當前頁(yè)數。

  分析完網(wǎng)頁(yè)的url組成以后,我們先解決第一個(gè)問(wèn)題:保存cookie,模擬登陸。

  打開(kāi)瀏覽器控制臺,選擇NetWork->Headers選項卡,可以看見(jiàn)懇求的headers信息。

  /img/remote/36683

  解決完以上問(wèn)題以后,讓我們嘗試寫(xiě)一下代碼獲取第1-100頁(yè)的網(wǎng)頁(yè)源碼:

  from urllib.parse import urlencode

import requests

base_url = ''

# 構造請求頭

headers = {

'Cookie': 'CXID=DF1F2AE56903B8B6289106D60E0C1339; SUID=F5959E3D8483920A000000005BCEB8CD; sw_uuid=3544458569; ssuid=8026096631; pex=C864C03270DED3DD8A06887A372DA219231FFAC25A9D64AE09E82AED12E416AC; SUV=00140F4F78C27EE25BF168CF5C981926; ad=p7R@vkllll2bio@ZlllllVsE@EclllllNBENLlllll9lllllpA7ll5@@@@@@@@@@; IPLOC=CN4110; ABTEST=2|1543456547|v1; weixinIndexVisited=1; sct=1; JSESSIONID=aaaXtNmDWRk5X5sEsy6Cw; PHPSESSID=lfgarg05due13kkgknnlbh3bq7; SUIR=EF72CF750D0876CFF631992E0D94BE34;',

'Host': '',

'Upgrade-Insecure-Requests': '1',

'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'

}

def get_html(url, count=1):

response = requests.get(url, allow_redirects=False, headers=headers)

# 判斷網(wǎng)頁(yè)返回的狀態(tài)碼是否正常

# 如果狀態(tài)碼是200說(shuō)明可以正常訪(fǎng)問(wèn)

if response.status_code == 200:

return response.text

# 如果狀態(tài)碼是302,則說(shuō)明IP已經(jīng)被封

if response.status_code == 302:

return None

def get_index(keyword, page):

data = {

'query': keyword,

'type': 2,

'page': page

}

queries = urlencode(data)

url = base_url + queries

html = get_html(url)

return html

def main():

for page in range(1, 101):

html = get_index('風(fēng)景', page)

print(html)

if __name__ == '__main__':

main()

  運行以上代碼,會(huì )發(fā)覺(jué)剛開(kāi)始運行正常,正確返回網(wǎng)頁(yè)源碼,之后便始終返回None,此時(shí)使我們打開(kāi)瀏覽器觀(guān)察一下:

  /img/remote/36684

  可以看出,代碼運行后不停返回None的緣由是網(wǎng)頁(yè)被重定向,需要輸入驗證碼能夠正常訪(fǎng)問(wèn),這便是我們開(kāi)篇說(shuō)過(guò)的第二個(gè)問(wèn)題,我們的訪(fǎng)問(wèn)被搜狗搜索的反爬蟲(chóng)舉措攔截,如果想要繼續正常訪(fǎng)問(wèn),便須要借助代理池獲取隨機代理來(lái)繞開(kāi)反爬機制。

  在使用Redis+Flask維護動(dòng)態(tài)代理池一文中,我們講解了代理池的基本原理和簡(jiǎn)單實(shí)現,代碼已托管到github上,現在使我們借助代理池來(lái)獲取隨機代理。

  首先使我們定義get_proxy()方法,返回代理池獲取的隨機可用ip:

  # flask*敏*感*詞*的是5000端口

PROXY_POOL_URL = ':5000/get'

def get_proxy():

try:

response = requests.get(PROXY_POOL_URL)

if response.status_code == 200:

return response.text

return None

except ConnectionError:

return None

  接下來(lái)更改get_html(url, count=1)方法,以隨機ip的形式訪(fǎng)問(wèn)網(wǎng)頁(yè):

  MAX_COUNT = 5

proxy = None

def get_html(url, count=1):

# 打印抓取的url

print('Crawling', url)

# 打印嘗試抓取的次數

print('Trying Count', count)

global proxy

# 如果抓取的次數大于最大次數,則返回None

if count >= MAX_COUNT:

print('Tried Too Many Counts')

return None

try:

if proxy:

proxies = {

'http': 'http://' + proxy

}

# allow_redirects=False:禁止瀏覽器自動(dòng)處理302跳轉

response = requests.get(url, allow_redirects=False, headers=headers, proxies=proxies)

else:

response = requests.get(url, allow_redirects=False, headers=headers)

if response.status_code == 200:

return response.text

# 狀態(tài)碼是302,說(shuō)明IP已經(jīng)被封,調用get_proxy()獲取新的ip

if response.status_code == 302:

# Need Proxy

print('302')

proxy = get_proxy()

if proxy:

print('Using Proxy', proxy)

return get_html(url)

else:

print('Get Proxy Failed')

return None

except ConnectionError as e:

# 如果連接超時(shí),重新調用get_html(url, count)方法

print('Error Occurred', e.args)

proxy = get_proxy()

count += 1

return get_html(url, count)

  再次運行代碼,會(huì )發(fā)覺(jué)不停重復復印None的情況基本消失。大家注意,這里是基本消失,原因是我們的代理池使用的是免費代理網(wǎng)站獲取的代理搜狗微信 反爬蟲(chóng),同一時(shí)刻可能會(huì )有許多人訪(fǎng)問(wèn),這樣就很容易導致ip地址被封的情況。如果你想要獲取更好的療效,不妨使用一下收費代理。

  至此,我們解決了開(kāi)篇提及的兩個(gè)問(wèn)題,接下來(lái),就可以抓取網(wǎng)頁(yè),分析內容。

  首先我們須要獲取到第1-100頁(yè)中每一篇文章的url:

  /img/remote/36685

  def parse_index(html):

doc = pq(html)

items = doc('.news-box .news-list li .txt-box h3 a').items()

for item in items:

yield item.attr('href')

def main():

for page in range(1, 101):

html = get_index(KEYWORD, page)

if html:

article_urls = parse_index(html)

print(article_urls)

  獲取到每一篇文章的url以后,就須要解析每一篇文章的內容。解析方式與前面相同,在此不再贅言。具體代碼如下:

  def parse_detail(html):

try:

doc = pq(html)

title = doc('.rich_media_title').text()

content = doc('.rich_media_content ').text()

date = doc('#publish_time').text()

nickname = doc('.rich_media_meta_list .rich_media_meta_nickname').text()

wechat = doc('#activity-name').text()

return {

'title': title,

'content': content,

'date': date,

'nickname': nickname,

'wechat': wechat

}

except XMLSyntaxError:

return None

  需要注意的一點(diǎn)就是須要捕獲XMLSyntaxError異常。

  最后使我們新建一個(gè)config.py文件,文件中包含了MongoDB的URL搜狗微信 反爬蟲(chóng),數據庫名稱(chēng),表名稱(chēng)等常量:

  MONGO_URL = 'localhost'

MONGO_DB = 'weixin'

  在spider.py中配置儲存到MongoDB相關(guān)方式:

  from config import *

import pymongo

client = pymongo.MongoClient(MONGO_URL)

db = client[MONGO_DB]

def save_to_mongo(data):

if db['articles'].update({'title': data['title']}, {'$set': data}, True):

print('Saved to Mongo', data['title'])

else:

print('Saved to Mongo Failed', data['title'])

  運行代碼,接下來(lái)在MongoDB中進(jìn)行查看:

  /img/remote/36686

  項目完整代碼已托管到github:

0 個(gè)評論

要回復文章請先登錄注冊


官方客服QQ群

微信人工客服

QQ人工客服


線(xiàn)

最近中文字幕2019高清,亚洲人成高清在线播放,男生淦哭男生图片动漫有字,国产亚洲精品九九久在线观看,无码av专区丝袜专区