要是直接访问iframe html url 就应该不用设置slenium中间件了,网页源代码有相关信息。明天看一下
goal 学scrapy 发送 post请求。要学的太多啦趴
1.spider文件
issue1:资料信息可能借助js加载,scrapy不能爬取到
solution: 在 middlewares.py 新建 SeleniumDownloadMiddleware类,使用slenium当作下载中间件,不过这种情况是模拟浏览器访问,网上有文章说可以借助其他模块操作。
issue2: 资料信息储存在iframe中,直接访问ifame所在页面获取不到infram信息
solution: 本次直接将iframe url 当作起始url ,或者将webdriver 对象swith_to到目标 iframe(未测试当前项目),不过使用 测试网页是可以
知识点:if else 居然可以写到一行,果然需要学的还很多
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from lxy.items import LxyItem
class LxyspiderSpider(CrawlSpider):
name = 'lxyspider'
allowed_domains = ['domain']
#start_urls = ['url'] # 教师信息在inframe里,需要switch_to iframe
start_urls = ['inframe'] #直接访问 iframe
#href="ShowJs.asp?id=266&xb="
rules = (
Rule(LinkExtractor(allow=r".*ShowJs.asp.+"),
callback='parse_js',
follow=False),)
print("rule ok")
def parse_js(self, response):
name = response.xpath('/html/body/table/tbody/tr/td/table[1]/tbody/tr[1]/td[3]/text()').get()
name = name if name else "无" #判断是否为空 m没有判断字符串为 “无”
xibp = response.xpath('/html/body/table/tbody/tr/td/table[1]/tbody/tr[1]/td[5]/text()').get()
xibp = xibp if xibp else "无"
viwu = response.xpath('/html/body/table/tbody/tr/td/table[1]/tbody/tr[2]/td[2]/text()').get()
viwu = viwu if viwu else "无"
lwbp = response.xpath('/html/body/table/tbody/tr/td/table[1]/tbody/tr[2]/td[4]/text()').get()
lwbp = lwbp if lwbp else "无"
xtli = response.xpath('/html/body/table/tbody/tr/td/table[1]/tbody/tr[3]/td[2]/text()').get()
xtli = xtli if xtli else "无"
xtww = response.xpath('/html/body/table/tbody/tr/td/table[1]/tbody/tr[3]/td[4]/text()').get()
xtww = xtww if xtww else "无"
dmhx = response.xpath('/html/body/table/tbody/tr/td/table[1]/tbody/tr[4]/td[2]/text()').get()
dmhx = dmhx if dmhx else "无"
yzxl = response.xpath('/html/body/table/tbody/tr/td/table[1]/tbody/tr[4]/td[4]/text()').get()
yzxl = yzxl if yzxl else "无"
item = LxyItem(
name = name,
xibp = xibp,
viwu = viwu,
lwbp = lwbp,
xtli = xtli,
xtww = xtww,
dmhx = dmhx,
yzxl = yzxl)
yield item
- middlewares配置
主要是定义seleniume 下载中间件,下载中间件也可以配置user_agent 选择 与ip 代理
isuue1 : 资料中含有电话的爬取不到,报错“Object of type Selector is not JSON serializable”
solution : 没有跟 get()
from scrapy import signals
import random
from selenium import webdriver
import time
from scrapy.http.response.html import HtmlResponse
class SeleniumDownloadMiddleware(object):
def __init__(self):
self.driver = webdriver.Chrome(
executable_path=r"D:\Anaconda\Scripts\chromedriver.exe"
)
def process_request(self,request,spider):
self.driver.get(request.url)
time.sleep(1)
source = self.driver.page_source
#包装成response 对象
response = HtmlResponse(url=self.driver.current_url,
body=source,
request=request,
encoding='utf-8'
)
print("response will be returned")
#print(response.body.decode())
return response #返回response给spider
- pipelines 文件
将信息储存为json文件
from scrapy.exporters import JsonLinesItemExporter
class LxyPipeline:
def __init__(self):
self.fp = open("lxyju.json","wb")
self.exporter = JsonLinesItemExporter(self.fp,
ensure_ascii=False,
encoding='utf-8')
def open_spider(self,spider):
print("="*6,"start","="*6)
pass
def process_item(self, item, spider):
self.exporter.export_item(item)
return item
def close_spider(self,spider):
self.fp.close()
4.setting配置
主要配置 下载延迟,user-agent ,开启 pipelines, 开启 middlewares
5.使用json 模块 读取 json文件,
issue: load好像不能读取很多行
读取文件,for 循环反序列化字符串,
Counter 可以计算list 频数,看到农学博士 农学硕士 理学博士人数较多
Counter({'PhD in Ecology': 1,
'博士(PhD)': 1,
'农学博士': 67,
'理学博士': 17,
'博士': 7,
'农学副博士': 1,
'工学博士': 2,
'农学硕士': 11,
'哲学博士(森林生态学专业)': 1,
'学士': 1,
'无': 5,
'理学硕士': 2,
'理学学士': 1,
'哲学博士': 2,
'植物营养学 博士': 1,
'文学硕士': 1,
'工学硕士': 1,
'教育学硕士': 1})
不使用selenium
issue: 可以爬取到 page source 但是没有返回关键信息,为None
solution: 应该是xpath 路径的问题,使用原先的full xpath 得不到内容。使用相对路径可以获取到内容,将response对象转换成html文件,full path 也是没有变化。 不确定什么原因。
不使用selenium 是很快,
网友评论