這兩天一直整一個大作業具體內容是從網站上爬取信件內容進行操作。這兩天一直在整這個內容,到現在是爬了出來。
網址:http://www.beijing.gov.cn/hudong/hdjl/com.web.search.mailList.flow
這是信件的網址老師給的網址已更新,這是我從同學哪里要的網址,有了網址,第一步是看要爬取的內容以及怎么獲取網站上的相關信息。

這是網站的頁面,我在點擊下一頁時發現並沒用跳轉頁面,所以覺得事情沒有那么簡單,通過查看后台的傳輸發現其實通過ajax傳輸信息的。

網站獲取的信息通過Ajax請求之后從http://www.beijing.gov.cn/hudong/hdjl/com.web.search.mailList.mailList.biz.ext獲得信息。
ajax傳輸信息參數

我有學習了簡單的scrapy爬蟲框架,首先通過命令行創建一個新的scrapy項目。相關命令
scrapy startproject 項目名 #創建項目
scrapy genspider 爬蟲名 網址 #生成spider文件(生成模板)
相關代碼
import json
import random
import string
import scrapy
class XinjianSpider(scrapy.Spider):
name = 'xinjian'
allowed_domains = ['www.beijing.gov.cn']
# custome_setting可用於自定義每個spider的設置,而setting.py中的都是全局屬性的,當你的
# scrapy工程里有多個spider的時候這個custom_setting就顯得很有用了
custom_settings = {
"DEFAULT_REQUEST_HEADERS": {
'authority': 'www.beijing.gov.cn',
# 請求報文可通過一個“Accept”報文頭屬性告訴服務端 客戶端接受什么類型的響應。
'accept': 'application/json, text/javascript, */*; q=0.01',
# 指定客戶端可接受的內容編碼
'accept-encoding': 'gzip, deflate',
# 指定客戶端可接受的語言類型
'accept-language': 'zh-CN,zh;q=0.9',
'Connection': 'keep-alive',
# 就是告訴服務器我參數內容的類型,該項會影響傳遞是from data還是payload傳遞
'Content-Type': 'text/json',
# 跨域的時候get,post都會顯示origin,同域的時候get不顯示origin,post顯示origin,說明請求從哪發起,僅僅包括協議和域名
'origin': 'http://www.beijing.gov.cn',
# 表示這個請求是從哪個URL過來的,原始資源的URI
'referer': 'http://www.beijing.gov.cn/hudong/hdjl/com.web.search.mailList.flow',
# 設置請求頭信息User-Agent來模擬瀏覽器
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36',
'x-requested-with': 'XMLHttpRequest',
# cookie也是報文屬性,傳輸過去
'cookie': 'HDJLJSID=39DBD6D5E12B9F0F8834E297FAFC973B; __jsluid_h=e6e550159f01ae9aceff30d191b09911; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2216f9edc47471cb-0059c45dfa78d6-c383f64-1049088-16f9edc474895%22%7D; _gscu_564121711=80128103kc5dx617; X-LB=1.1.44.637df82f; _va_ref=%5B%22%22%2C%22%22%2C1580462724%2C%22https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DM-f5ankfbAnnYIH43aTQ0bvcFij9-hVxwm64pCc6rhCu5DYwg6xEVis-OVjqGinh%26wd%3D%26eqid%3Dd6b151bf000cfb36000000025e1c5d84%22%5D; _va_ses=*; route=74cee48a71a9ef78636a55b3fa493f67; _va_id=b24752d801da28d7.1578917255.10.1580462811.1580450943.',
}
}
# 需要重寫start_requests方法
def start_requests(self):
# 網頁里ajax鏈接
url = "http://www.beijing.gov.cn/hudong/hdjl/com.web.search.mailList.mailList.biz.ext"
# 所有請求集合
requests = []
for i in range(0, 33750,1000):
random_random = random.random()
# 封裝post請求體參數
my_data = {'PageCond/begin': i, 'PageCond/length': 1000, 'PageCond/isCount': 'true', 'keywords': '',
'orgids': '', 'startDate': '', 'endDate': '', 'letterType': '', 'letterStatue': ''}
# 模擬ajax發送post請求
request = scrapy.http.Request(url, method='POST',
callback=self.parse_model,
body=json.dumps(my_data),
encoding='utf-8')
requests.append(request)
return requests
def parse_model(self, response):
# 可以利用json庫解析返回來得數據
jsonBody = json.loads(response.body)
print(jsonBody)
size = jsonBody['PageCond']['size']
data = jsonBody['mailList']
listdata = {}
for i in range(size):
print(i)
listdata['letter_type'] = data[i]['letter_type']
listdata['original_id'] = data[i]['original_id']
listdata['catalog_id'] =str(data[i]['catalog_id'])
listdata['letter_title'] = data[i]['letter_title']
listdata['create_date'] = data[i]['create_date']
listdata['org_id'] = data[i]['org_id']
listdata['letter_status'] = data[i]['letter_status']
yield listdata
print(listdata)
item.py
class DataItem(scrapy.Item):
letter_type=scrapy.Field()
original_id = scrapy.Field()
catalog_id = scrapy.Field()
letter_title = scrapy.Field()
create_date = scrapy.Field()
org_id = scrapy.Field()
letter_status = scrapy.Field()
setting.py
BOT_NAME = 'xinjian' SPIDER_MODULES = ['freebuf.freebuf.spiders'] NEWSPIDER_MODULE = 'freebuf.freebuf.spiders.testSpider'
之后通過在命令行進入項目目錄輸入scrapy crawl xinjian-o data.csv 來運行項目其中-o表示保存文件
附最后截圖:

遇到的問題:
目標服務器連接被拒絕之類的······


原因:請求此時過多,我之前是六個一請求,
解決方案:將請求的長度變大每次請求1000個,減少請求次數
